【问题标题】:List of Generics T using Interface使用接口的泛型 T 列表
【发布时间】:2014-03-14 14:13:05
【问题描述】:

遵循这两个 SO 问题:

Is it possible to use a list of untyped generics in C#?

How am I able to create A List<T> containing an open generic Interface?

  public interface IValue
{
    object Min { get; set; }
    object Max { get; set; }
    object Avg { get; set; }
}

public abstract class Value<T> : IValue
{
     abstract T Min;
     abstract T Max;
     abstract T Avg;
    object IValue.Avg { get { return Avg; } }
    object IValue.Min { get { return Min; } }
    object IValue.Max { get { return Max; } }

    public Value(T min, T max, T avg)
    {
        Min = min;
        Max= max;
        Avg = avg;
    }
}

代码中的其他地方......

Value myValue = new Value<ulong>(x, y, z);
Value myValue = new Value<ushort>(x, y, z);
List<IValue> myList = new List<IValue>();
myList.add(myValue);
//Do stuff like myList[0].Min

我无法让它正常工作。我想象它与我的界面以及我如何使用它有关。我希望能够调用构造函数并设置我需要的值。

我收到诸如“修饰符'抽象'在字段上无效。请尝试使用属性”和“无法创建接口值抽象类的实例”之类的错误,但我也无法执行新的 IValue。

【问题讨论】:

  • 抽象属性对你有用吗?无论如何,为什么价值是抽象的?对我来说看起来很具体。
  • 就是一个例子。我也可以使用 ,反之亦然。
  • @user999999928 这并没有改变这样一个事实,即不需要抽象类型。它是通用的,所以它可以接受不同类型的参数而不是抽象的。
  • 啊,对不起,误会了。关键是我想创建一个 List> ,根据另一个 SO,您需要创建一个在 Value 类中具有抽象值的接口。
  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。

标签: c# list generics


【解决方案1】:
  • 你不能创建一个接口的对象,所以你不能做new IValue()

  • 你不能创建抽象类型的对象,所以你也不能new Value&lt;SomeType&gt;()

  • Value&lt;T&gt;MinMaxAvg中是字段,字段不能是抽象的。您想改为创建属性:

    public abstract T Min { get; set; }
    public abstract T Max { get; set; }
    public abstract T Avg { get; set; }
    
  • 您可能根本不想使用abstractValue&lt;T&gt; 看起来很完整,并且鉴于您希望能够创建它,没有理由将其作为抽象类型。

【讨论】:

  • 您的最后一点并非如此。没有可能的类型可以用作不能隐式转换为object 的通用参数,因此该部分可以正常工作。是的,它不提供对每个值的基础类型的访问,但如果他不需要,那么他的代码仍然可以工作。如果他愿意,他可以在界面之外提供强类型访问,但对于他目前所展示的内容来说,这并不是需要
  • @Servy 如果你明确地实现它,是的。但是,如果您只是尝试将T Min 作为接口的object Min 的实现,那么这是行不通的。
  • 但这不是他所做的。如果您查看问题中的实际代码,他会正确实现该接口。你指出了一个他明确没有犯的错误。
  • @Servy 是的,我确实指出 OP 明确地实现了接口。我还指出,在原始代码中,接口名称错误(因此,OP 没有正确实现IValue)。我现在删除了该部分,但显然指出了 OP 可能知道使人们感到困惑的事情……
  • 是的,对于错误命名的统计值,我们深表歉意。在看到您的回复之前,我在 OP 中修复了它。摘要让我失望,因为我只是在关注其他 SO Question 所做的事情,而没有意识到他的课程最初是抽象的。傻我。在这种情况下,我根本不想要抽象。但是,在删除摘要时,当我意识到我的 set 方法也搞砸了时,我仍然无法让新的 Value(x,y,z) 正常工作。
【解决方案2】:

你为什么要使用abstract?如果你想创建类实例,类不能是抽象

public class Value<T>: IValue {
  // Better to name these fields as "min, max, ave" or "m_Min, m_Max, m_Ave"
  T Min;
  T Max;
  T Avg;

  // Do not forget about "set" accessors
  object IValue.Avg {
    get { return Avg; }
    set { Avg = (T) value; }
  }

  object IValue.Min {
    get { return Min; }
    set { Min = (T) value; }
  }

  object IValue.Max {
    get { return Max; }
    set { Max = (T) value; }
  }

  public Value(T min, T max, T avg) {
    Min = min;
    Max = max;
    Avg = avg;
  }
}

...

// "Value<ulong> myValue" instead of "Value myValue "
Value<ulong> myValue = new Value<ulong>(x, y, z);
List<IValue> myList = new List<IValue>();
myList.Add(myValue);

【讨论】:

  • 谢谢你,你是对的。我根本不想抽象。当我犯了误读的错误时,我只是想关注另一个相关的问题。但是当我尝试不使用抽象时,我仍然无法执行 newValue(x,y,z) 然后,在您回复之后,我突然意识到我没有执行 set { Min = (T) value)。这解决了整个事情。我现在有一个正确的 Value 泛型列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-11
  • 2012-03-01
  • 2012-02-25
相关资源
最近更新 更多