【问题标题】:c# list of interface with generic itemsc# 带有通用项的接口列表
【发布时间】:2012-08-08 04:35:59
【问题描述】:

我的问题有点类似于 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
}

我不确定这怎么可能。

谢谢, 抢

【问题讨论】:

    标签: c# list generics interface generic-list


    【解决方案1】:

    您可以利用 dynamic

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

    动态类型允许其发生的操作绕过编译时类型检查。相反,这些操作是在运行时解决的

    【讨论】:

      【解决方案2】:

      你可以这样做:

      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 时,您可以将值作为对象取出。

      【讨论】:

      • 感谢您的回复,但是这使得使用泛型毫无意义,我可以只使用对象值并摆脱所有泛型的东西
      • 它根本不会使泛型变得毫无意义。你所有的原始优点都在那里 - 当你不知道泛型类型参数时,这只是提供了一种简单的方法来获取值。它不会以任何方式诋毁您现有的代码。
      • 对不起,我不清楚,在我的具体情况下,它对我没有帮助,因为我没有将接口用于除此列表之外的任何其他内容并获取价值。在其他情况下,您的答案可能是合适的。
      【解决方案3】:

      当然不是,你的值将是不同的类型......所以你必须向下转换为真正的类型才能获得不同的值。

      基本上你的界面是失败的。不是“通用接口”,而是“相似接口”

      如果你不想进行强制转换,那么你将不得不找到一个对它们都通用的接口。

      【讨论】:

        【解决方案4】:

        您可以将Value 属性移动到基本接口。

        public interface IPrimitive
        {
             object Value { get; }
        }
        

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

        【讨论】:

        • 我正在将值添加到通用集合中
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多