![](/img/trans.png)
[英]How to access the object's specific properties from a list of objects sharing the same 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.