C#中的接口列表与泛型项

3
我的问题有点类似于Generic List of Generic Interfaces not allowed, any alternative approaches? 如果我有这样一个接口:
public interface IPrimitive
{

}

public interface IPrimitive<T> : IPrimitive
{
     T Value { get; }
}

public class Star : IPrimitive<string> //must declare T here
{
    public string Value { get { return "foobar"; } }
}

public class Sun : IPrimitive<int>
{
    public int Value { get { return 0; } }
}

然后我有一个列表

var myList = new List<IPrimitive>();
myList.Add(new Star());
myList.Add(new Sun());

当遍历这个列表时,如何获取Value属性?
foreach (var item in myList)
{
    var value = item.Value; // Value is not defined in IPrimitive so it doesn't know what it is
}

我不确定这是否可能。

谢谢, 罗布

4个回答

4
你可以利用“动态”:

您可以利用动态

foreach (dynamic item in myList) 
{ 
    var value = item.Value; 
} 

动态类型使其所在的操作可以绕过编译时类型检查。相反,这些操作在运行时解决。

3
你可以这样做:
public interface IPrimitive
{
    object Value { get; }
}

public interface IPrimitive<T> : IPrimitive
{
    new T Value { get; }
}

public class Star : IPrimitive<string> //must declare T here
{
    public string Value { get { return "foobar"; } }
    object IPrimitive.Value { get { return this.Value; } }
}

public class Sun : IPrimitive<int>
{
    public int Value { get { return 0; } }
    object IPrimitive.Value { get { return this.Value; } }
}

当你只有 IPrimitive 时,你可以将其作为对象获取值。

1
感谢您的回复,但这使得使用泛型毫无意义,我可以只使用对象值并摆脱所有泛型内容。 - QldRobbo
1
这并不意味着泛型变得毫无意义。所有原始的好处都在那里 - 这只是提供了一种简单的方法,在你不知道泛型类型参数时获取值。它不会以任何方式贬低你现有的代码。 - Enigmativity
1
抱歉,我的表述可能不够清晰,在我的特定情况下,这并不能帮助我,因为我除了获取值和列表之外,并没有使用接口。在其他情况下,您的回答可能是适当的。 - QldRobbo

2
当然不是,您的值将会是不同的类型.....所以您需要向下转换为真实类型才能获取不同的值。
基本上,您的接口出现了问题。它不是“通用接口”,而更像是“类似接口”。
如果您不想进行转换,则必须找到两者都通用的接口。

0
你可以将你的 Value 属性移动到基础接口。
public interface IPrimitive
{
     object Value { get; }
}

你想如何在循环中处理类型不同的value


我正在将值添加到通用集合中。 - QldRobbo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接