继承具有List <interface>的接口作为属性问题</interface>

时间:2012-08-22 20:46:26

标签: c# .net list interface

我有两个接口,一个包含另一个接口的列表,我希望有一个实现第一个接口的类,但是有一个实现第二个接口而不仅仅是接口列表的另一个类的列表。例如:

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; }
    }
}

显然它不喜欢这个。是否有正确的方法来做我想做的事情,或者我只需要让BookShelf拥有List<IBook>并将每个IBook投放到Book时我想用它吗?寻找可以帮助我在这里的模式。感谢。

4 个答案:

答案 0 :(得分: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; }
} 

答案 1 :(得分:2)

目前尚不清楚 正在尝试做什么 - 而且怀疑它甚至不清楚。为什么您特别希望BookShelf.Books成为List<Book>?为什么限制本身仅包含Book值而不是IBook值?我建议你考虑在这种情况下你想要发生什么:

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

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

该代码中没有任何内容可疑 1 ,包含您提供的接口 - 但最终会在EvilBook中添加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界面...以及您是否真的需要{{1}的公共可写属性}。


1 无论如何,编译器会认识到:)

答案 2 :(得分: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; }
    }
}

答案 3 :(得分:0)

  1. 一般来说,施法是可疑的,最好避免。这是一个很好的信号,表明某些事情是不对的。

  2. 修复需要更改的代码

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

    public List<IBook> Books { get; set; }
    
  3. 你可以而且应该更多地概括一些事情。什么样的书架不允许其他物品?我还没看到一个。考虑一下:

  4. 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'
        }
    }
    

    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' } }