繁体   English   中英

如何访问列表<Interface>从接口继承类时的对象属性?

[英]How to access List<Interface> object properties when it's class is inherited from interface?

好的,问题来了。 我有一个接口 IBook,其中包括属性名称。 有两个类继承自 IBook 并添加了自己的属性 Genre。 我想创建一个字典或一个列表,并在那里添加各种书籍并通过字符串及其属性访问它们,所以我制作了字典。 在示例中,我可以访问 books["LOTR"].Name 但不能访问 books["LOTR"].Genre,这可能是因为 Name 是 IBook 接口的属性,而 Genre 是从 IBook 继承的类的属性。

是否可以使 Dictionary 或 List 与接口类型一起使用并且仍然能够访问所有继承类属性,还是应该使用数组或其他东西?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp124
{
interface IBook
{
    string Name { get; set; }
}

public class FantasyBook:IBook
{
    string name;
    string genre;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }
    public string Genre
    {
        get { return genre; }
        set { genre = value; }
    }
}
public class HorrorBook : IBook
{
    string name;
    string genre;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }
    public string Genre
    {
        get { return genre; }
        set { genre = value; }
    }
}
class Program
{
    static void Main(string[] args)
    {
        FantasyBook LordOfTheRings = new FantasyBook();
        HorrorBook Frankenstein = new HorrorBook();
        Dictionary<string, IBook> books = new Dictionary<string, 
IBook>();

        books.Add("LOTR", LordOfTheRings);
        books.Add("Frankenstein", Frankenstein);
        books["LOTR"].Name = "Lord Of The Rings";
        books["LOTR"].Genre = "Fantasy";
        Console.ReadLine();
    }
}
}

另一种方法是添加另一层与Genre的接口,并使用模式匹配来访问属性:

interface IBook
{
    string Name { get; set; }
}

interface IBookWithGenre : IBook
{
    string Genre { get; set; }
}

public class FantasyBook : IBookWithGenre
{
    public string Name { get; set; }
    public string Genre { get; set; }
}
public class HorrorBook : IBookWithGenre
{
    public string Name { get; set; }
    public string Genre { get; set; }
}

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

class Program
{
    static void Main(string[] args)
    {
        FantasyBook LordOfTheRings = new FantasyBook();
        HorrorBook Frankenstein = new HorrorBook();
        SimpleBook abook = new SimpleBook();
        var books = new Dictionary<string, IBook>
        {
            { "LOTR", LordOfTheRings },
            { "Frankenstein", Frankenstein },
            { "Simple", abook },
        };
        books["LOTR"].Name = "Lord Of The Rings";
        if (books["LOTR"] is IBookWithGenre withGenre)
        {
            withGenre.Genre = "Fantasy";
        }
        Console.ReadLine();
    }
}

评论非常重要 - 您不能这样做,因为编译器将检查IBook上的可用成员(因为您声明了它),并且不会让您尝试访问未在其中定义的属性,从而使自己陷入IBook 这是静态类型检查

但是让我们再想象一下你不关心类型安全和性能。 事实证明,你有一个选择。 嗯,有点......因为你仍然需要放弃你的特定IBook以获得dynamic

interface IBook {
    string Name { get; set; }
}

public class FantasyBook : IBook
{
    public string Name { get; set; }
    public string Genre { get; set; }
}
public class HorrorBook : IBook
{
    public string Name {get;set;}
    public string Genre {get;set;}
}

public class BadaBook : IBook // so I added this new class that does not implement Genre to illustrate a point
{
    public string Name { get; set; }
}
static void Main(string[] args)
    {
        var LordOfTheRings = new FantasyBook();
        var Frankenstein = new HorrorBook();
        var Badaboom = new BadaBook();
        Dictionary<string, dynamic> books = new Dictionary<string, dynamic>();

        books.Add("LOTR", LordOfTheRings);
        books.Add("Frankenstein", Frankenstein);
        books.Add("Badaboom", Badaboom);
        books["LOTR"].Name = "Lord Of The Rings";
        books["LOTR"].Genre = "Fantasy";
        books["Badaboom"].Name = "We can easily assign Name as it is defined. No problem here";
        books["Badaboom"].Genre = "But we will miserably fail here"; // RuntimeBinderException: 'UserQuery.BadaBook' does not contain a definition for 'Genre'

        Console.ReadLine();
    }

查看动态以进一步阅读。 它伴随着我的示例中概述的风险以及性能损失。 它本身并不坏,只是需要适度服用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM