【发布时间】:2013-12-15 17:37:23
【问题描述】:
跟进这个问题:Why is Nullable<T> considered a struct and not a class?
我有两个类,它们本质上是使用内部对象维护一些用户提供的值的元组。
当用户提供的值的类型是原始类型时,我必须将其包装在 Nullable<T> 中,以便它可以在元组中采用空值。
public class BundledClass<T> where T : class
{
private Tuple<T, object> _bundle;
public T Value
{
get { return _bundle == null ? null : _bundle.Item1; }
set { _bundle = new Tuple<T, object>(value, internalObj); }
}
//...
public class BundledPrimitive<T> where T : struct
{
private Tuple<T?, object> _bundle;
public T? Value
{
get { return _bundle == null ? null : _bundle.Item1; }
set { _bundle = new Tuple<T?, object>(value, internalObj); }
}
//...
如果我可以使用可以将基元或类作为类型参数的单个类来执行此操作,我会更喜欢它,但我看不到任何解决方法。并非没有想出某种自定义的Nullable 类,它可以装箱任何类型(不仅仅是类型where T:struct),以确保始终可以将Value 分配为null;
看来我至少应该能够将后一个类定义为
public class BundledPrimitive<T> : BundledClass<T?> { }
但即使这样也失败了,因为 Nullable<T> 不符合 : class 约束(根据链接的问题)。
【问题讨论】:
-
如果我是这个类的用户,如何区分
Value未设置和我在程序的其他地方将Value设置为 null? -
@mikez 如果从未设置过该值,则使用内部
_bundle = null。如果Value设置为空,则内部_bundle将是Tuple<T, object>(null, internalObj)。这并不重要,但用户可以使用返回_bundle的公共 get-only 属性看到这一点。 -
是的,这将是内部状态的差异,但作为调用者,我无权访问
_bundle。 -
@Alain BTW,我在答案中选择了名称
BundledStruct而不是BundledPrimitive,因为两者并不完全相同。DateTime是结构体但不是原语,string是 C# 中的原语(虽然Type.IsPrimitive会返回 false),但它不是结构体。
标签: c# generics nullable type-constraints