如何向编译器承诺泛型类型将具有某种属性?

时间:2014-02-28 17:53:55

标签: c# generics

我想对多个变量类型(本机和对象)使用某个操作,所以我使用泛型返回类型如下。

private Generic Field<Generic>(String field)
{
  if (BagOfJunk.Properties.Contains(field))
    return (Generic)BagOfJunk[field];
  return default(Generic);
}

这很好用( BagOfJunk 只是 this 的一个属性,我从中取出 Object 类型的值)。现在,在运行时,当包中没有包含字段时,我得到默认值 null 。因此,在代码中,我需要执行如下检查。

NumericType protoNumber = Field<NumericType>("beep");
int number = protoNumber != null ? protoNumber.Value : -1;

DateType protoDate = Field<DateType>("boop");
DateTime date = protoDate != null ? protoDate.Value : null;

我想使代码更紧凑,所以我尝试设计一种方法,一次性执行上述四行,对于泛型类型。结果如下,但当然,它不会编译,因为 GenericIn 类型不够具体,不具有属性 Value

private GenericOut Field<GenericIn, GenericOut>(String field)
{
  GenericIn input = Field<GenericIn>(field);
  if (input != null)
    return (GenericOut)input.Value;
  return default(GenericOut);
}

如何确保我的 GenericIn 不是通用的计算机 - 通过承诺无论我推入什么内容,它总是拥有属性 Value 在它?

修改

应该强调的是, Value 的类型必须是通用的(相当于 GenericOut )。我注意到我的压力不够强烈。因此,可以使用的接口需要声明一般类型的属性,如下所示。

interface ObjectWithValue { public Generic Value { get; } }

3 个答案:

答案 0 :(得分:4)

您可以使用接口并对类型应用where约束来实现该接口,如下所示:

interface IHasPropertyValue<TValue> {
  TValue Value { get; }
}

class MyType {
  public TValue Method<T, TValue>(T obj) where T : IHasPropertyValue<TValue> {
    return obj.Value;
  }
}

编辑:修改了上面的代码,使其更加具体到下面提到的评论。

答案 1 :(得分:1)

将该属性放在接口(或类)中,并使用泛型约束“where”:

public interface IMyInterface
{
    public object Value { get; set; }
}

public class C<T> where T:IMyInterface

答案 2 :(得分:1)

要构建到目前为止的答案,您需要创建一个由GenericIn实现的接口,它将保证它具有属性Value并且该属性的类型为{ {1}}。

GenericOut