3

2 つのインターフェイスがあり、一方には他方のリストが含まれています。最初のインターフェイスを実装するクラスが必要ですが、インターフェイスの単なるリストではなく、2 番目のインターフェイスを実装する別のクラスのリストが必要です。例:

namespace TestInheritance
{
    public interface IBookShelf
    {
        long Stuff { get; set; }
        List<IBook> Books { get; set; }
    }
    public interface IBook
    {
        string Name { get; set; }
    }
    public class BookShelf : IBookShelf
    {
        public long Stuff { get; set; }
        public List<Book> Books { get; set; }
    }
    public class Book : IBook
    {
        public string Name { get; set; }
    }
}

明らかに、これは好きではありません。私がやろうとしていることを行う正しい方法はありますか、それとも、使用したいときにa を作成し、それぞれを aBookShelfList<IBook>キャストする必要がありますか? ここで私を助けることができるパターンを探しています。ありがとう。IBookBook

4

4 に答える 4

4

IBookShelfジェネリック引数を制約する場所をジェネリックにすることができますIBook

次に、次のことができます。

public interface IBookShelf<T> where T : IBook
{
    long Stuff { get; set; }
    List<T> Books { get; set; }
}

public class BookShelf : IBookShelf<Book>
{
    public long Stuff { get; set; }
    public List<Book> Books { get; set; }
} 
于 2012-08-22T20:51:17.263 に答える
2

あなたが何をしようとしているのか正確には明らかではありません - そして私それがあなたにも明らかではないのではないかと思います. BookShelf.Books特になりたい理由は何List<Book>ですか?値ではなく値のみを含めるように制限しているのはなぜですか? この状況で何が起こりたいかを検討することをお勧めします。BookIBook

public class EvilBook : IBook
{
    public string Name { get; set; }
}

IBookShelf bookShelf = new BookShelf() { Books = new List<Book>() };
bookShelf.Books.Add(new EvilBook());

そのコードには疑わしいものはありません1、指定したインターフェイスを使用しますが、最終的EvilBookに a に aを追加しますがList<Book>、これは確かに正しくありません。コンパイラーが何かをするのを止めている場合、私の悪い考えを先に進めさせた場合にどのような問題が発生する可能性があるかを考えると役立つことがよくあります。

ジェネリックにすることを検討したいかもしれません:IBookShelf

public interface IBookShelf<T> where T : IBook
{
    long Stuff { get; set; }
    List<T> Books { get; set; }
}

それで:

public class BookShelf : IBookShelf<Book>

...しかし、それは実際に何を達成しようとしているかによって異なります。

IBookまた、そもそもインターフェイスが本当に必要かどうかを自問することもできます...また、Books.


1とにかく、コンパイラが認識する用語:)

于 2012-08-22T20:51:21.180 に答える
0
  1. 一般的に言えば、キャスティングは疑わしいため、避けるのが最善です。何かが正しくないという素晴らしいシグナルです。

  2. コードを修正するには、変更する必要があります

    public List<Book> Books { get; set; }
    

    public List<IBook> Books { get; set; }
    
  3. 物事をもっと一般化できますし、そうすべきです。他のものを上に置くことができない本棚はどのようなものですか? 私はまだ 1 つを参照してください。このことを考慮:

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
public interface IShelf
{
    long Stuff { get; }
    List<IShelfItem> Items { get; }
}
public interface IShelfItem
{
    string Name { get; }
    string Thought {get; set;}//What do I think about it?
}
public class Shelf : IShelf
{
    public Shelf(long stuff, string color) 
    {
        Stuff = stuff;
        Items = new List<IShelfItem>();
        Color = color;
    }

    public long Stuff { get; private set; }
    public List<IShelfItem> Items { get; private set; }//Note, you can still add to the list.
    public string Color { get; set; }

}
public class Book : IShelfItem
{
    public Book( string name, string thought ) {
        Name = name;
        Thought = thought;
    }
    public string Name { get; private set; }//Books that are on shelves don't really change their name;
    public string Thought { get; set; }

    public string BookSpecificProperty { get; set; }
}


public static void Main()
{
    Shelf myShelf = new Shelf(42, "Dull boring grey");

    myShelf.Color = "Red";


    IShelf myIShelf = myShelf;
    //myIShelf.Color = "Red"; - 'IShelf' does not contain a definition for 'Color'

    myShelf.Items.Add( new Book("Title 1", "Such a great book" ) );

    //Eos pass

    var book = myShelf.Items.SingleOrDefault( i => i.Name == "Title 1" );
    if( book != null ) {
        book.Thought = "I used to think it was such a great book. It's just OK";
        //book.BookSpecificProperty = "X"; - 'IShelfItem' does not contain a definition for 'BookSpecificProperty'
    }
}

于 2016-02-15T13:47:57.007 に答える
0

このようなものはどうですか:

namespace TestInheritance
{
    public interface IBookShelf <TBook> where TBook : IBook
    {
        long Stuff { get; set; }
        List<TBook> Books { get; set; }
    }
    public interface IBook
    {
        string Name { get; set; }
    }
    public class BookShelf : IBookShelf<Book>
    {
        public long Stuff { get; set; }
        public List<Book> Books { get; set; }
    }
    public class Book : IBook
    {
        public string Name { get; set; }
    }
}
于 2012-08-22T20:52:24.787 に答える