我写了一个通用类
class MyClass : MyClass<string> { } //this line is in error
class MyClass<OutputBaseType> : MyClass<OutputBaseType, List<OutputBaseType>>
where OutputBaseType : new() //this new constraint is needed
{}
class MyClass<OutputBaseType,OutputType>
where OutputType : ICollection<OutputBaseType>, new()
where OutputBaseType : new()
{
public void Method(OutputBaseType z)
{
if (z!=null) { ... }
}
...
}
因为string没有默认构造函数,所以第一行现在可以工作。如果我删除此行并修改客户端以显式定义字符串,则由于相同的原因它不起作用。
如果我删除了where OutputBaseType : new()
而另一个new()
,那么它适用于OutputBaseType
的{{1}},而不是string
OutputType
。这是因为字典使用的dictionary<...>
是KeyValuePair<>
而不是struct
,因此不能是class
。 (我不喜欢null,但在这里需要它)
有没有办法让它发挥作用?
修正:
我删除了OutputBaseType的新约束。 然后替换为null的赋值并使用默认构造赋值,默认(OutputBaseType)
这看起来很有希望,但我现在在行
上的条件表达式中有错误null
错误是:
OutputBaseType outputItem = ...;
if (outputItem != default(OutputBaseType)) { _Output.Add(outputItem); }
答案 0 :(得分:4)
如果我删除OutputBaseType:new()和另一个new(),那么它可以使用字符串OutputBaseType,但不能使用字典作为OutputType。这是因为KeyValuePair&lt;&gt;字典使用的是结构而不是类,因此不能为null。 (我不喜欢null,但在这里需要它)
您只需使用default(T)
代替null
作为值类型。值类型的默认构造函数不能由用户定义,并始终将所有字段初始化为其默认值(0
,null
,...)。因此,如果您只使用new()
而不是default(T)
,则不需要new T()
约束,因为对于值类型它们是等效的,对于您想要的引用类型null
恰好是任何引用类型的default
。
==
在通用类型上不可用。您可以使用object.Equals
(这会导致装箱)或EqualityComparer<T>.Default.Equals
。我更喜欢第二个:
EqualityComparer<T>.Default.Equals(outputItem, default(OutputBaseType))
答案 1 :(得分:0)
: new()
约束意味着“类型必须具有无参数构造函数”,并允许您在泛型类中使用new T()
。 System.String
没有无参数构造函数,因此您无法执行new String()
,这意味着它不满足: new()
类型约束。
也许你想要: class
?这并没有说明构造函数,它只是说它必须是一个引用类型。这样您就可以在类中使用!= null
,并允许您使用String
作为类型参数。