是否可以在一个接口的字典中访问多个接口?

Is it possible to access multiple interfaces in a dictionary of one interface?

首先:抱歉,如果问题措辞奇怪。我是 C# 多类化的新手,我有点卡住了。

我目前正在制作一个库存系统,该系统对所有项目使用一个字典。项目本身是不同的 类,并使用属性接口。为简单起见,假设这些是接口。一个接口有名称,第二个有特定值,第三个有另一个特定值。

我似乎无法弄清楚如何(如果可能)访问第二个界面的属性,因为我得到的唯一建议是字典中使用的项目类型。

// the interface examples
interface IStandardProperties
{
   string Name { get; set; } 
}

interface IItemType1
{ 
    int SomeValue { get; set; } 
}

interface IItemType2
{ 
    int AnotherValue { get; set; } 
}

// Then we have two classes that uses these. 
class ItemType1 : IStandardProperties, IItemType1
{ 
    public string Name; 
    public int SomeValue;
    public ItemType1() 
    {
       this.Name = "Item type 1"; this.SomeValue = "10";
    }
}

class ItemType2 : IStandardProperties, IItemtype2
{
    public string Name; 
    public int SomeValue;
    public ItemType1() 
    { 
        this.Name = "Item type 1"; 
        this.AnotherValue = "100";
    }
}

// and finally the dictionary in question.

Dictionary<int, IStandardProperties> items = New Dictionary<int, IStandardProperties>();

现在,这两项都可以存储在字典中,但是我似乎无法弄清楚如何(或者如果可能的话)通过字典访问存储在 SomeValue 和 AnotherValue 的接口属性中的值。我看过几个使用 "as InterfaceName" 的示例,但我不确定它的用法。

有没有办法访问这些? (万一我对接口有严重的误解,这些值是否存储在字典中?

我在任何方面都不是专家,所以我希望您能就此事提供任何更正或帮助。

当您创建 Dictionary<int, IStandardProperties> 时,我们唯一确定的是 每个 项目都实现了该特定接口。

如果你要问 AnotherValue 属性 类型的项目 ItemType1,你显然不会做正确的事情。这就是为什么您的字典项目无法显示此 属性:它们不是您字典中每个元素的属性

您可以通过类型检查实现所需的方法:

if (items[0] is IItemType1) {
    (items[0] as IItemType1).SomeValue ... 
} 
if (items[0] is IItemType2) {
    (items[0] as IItemType2).AnotherValue ... 
}

这将检查该项目是否实现了所述接口,然后才访问该接口的成员 (属性)

如果我理解正确你的问题,这一行

class ItemType1 : IStandardProperties, IItemType1

声明 ItemType1 实现了 IStandardPropertiesIItemType1,这意味着它具有 两个 特征。

你的词典声明

Dictionary<int, IStandardProperties> items = New Dictionary<int, IStandardProperties>();

说你的字典是从 intIStandardProperties 键入的。这意味着字典的值是 known 并且 enforcedIStandardProperties 类型。 但是,这并不能说明你的价值特征有多大可能。

因此,您必须在需要时询问特定特征(请注意,从 C# 7 开始有一些快捷方式,我故意避免了):

IStandardProperties v; 
if (items.TryGetValue("key", out v))
{
    // found. the line below asks if the interface is supported
    var item1 = v as IItemType1;
    if (item1 != null)
    {
        // v supports IItemType1, therefore you can do something with it, by using item1
    }

    // we repeat for IItemType2
    var item2 = v as IItemType2;
    if (item2 != null)
    {
        // v supports IItemType2, therefore you can do something with it, by using item2
    }

}
else
{
    // not found
}