我认为首先是一个代码示例。我正在尝试构建一个视图模型,我将用于所有需要下拉控件的属性,这是一个开始:
public class ListProperty<TListItem, TValue>
{
private readonly string _valuePropertyName = "Id";
private readonly string _textPropertyName = "Name";
public TValue Value { get; set; }
private IEnumerable<TListItem> _list;
public ListProperty(IEnumerable<TListItem> list)
{
_list = list;
}
}
我希望Value
的基础属性始终可以为空,因此如果TValue
是引用类型,则基础类型将只是TValue
,但是TValue
时Nullable<TValue>
1}}是值类型,基础类型必须是Value
。
更多信息:我想要这个的原因是要知道是否已分配Object
属性。要做到这一点,没有我的要求将涉及必须键入值{{1}},这对我来说闻起来很糟糕。
答案 0 :(得分:3)
这是不可能的。 C#可空语法T?
(主要)是System.Nullable<T>
的快捷方式。 System.Nullable
不允许T
的引用类型。这就是为什么你不能将?
应用于可能是引用类型的(泛型)类型的原因。不过,您可以将TValue
限制为struct
。
或者,您可以编写自己的Nullable
辅助结构,允许引用类型。
答案 1 :(得分:1)
您可以尝试将它们分成不同的类:
public abstract class ListProperty<TListItem, TValue> {
public TValue Value { get; set; }
...
}
public class RefListProperty<TListItem, TValue> :
ListProperty<TListItem, TValue> where TValue : class {
}
public class ValListProperty<TListItem, TValue> :
ListProperty<TListItem, Nullable<TValue>> where TValue : struct {
}
答案 2 :(得分:1)
我能想到的最好的方法是传递三个参数,只传递一个或另一个:
public class ListProperty<TListItem, TValueStruct, TValueClass>
where TValueStruct : struct
where TValueClass : class
{
}
答案 3 :(得分:1)
简单和简短:因为你需要在不同的地方实例化不同的版本,为什么不呢
ListProperty<SomeListItemType, SomeReferenceType>
和
ListProperty<SomeOtherListItemType, SomeValueType?>
在适当的地方?但也许我有些不对劲......
答案 4 :(得分:0)
我不确定我是否理解你的问题,但是现在你的班级已经存在,你可以使用TValue
的任何类型,包括可以为空的类型:
new ListProperty<string, string>(someList1); // reference type: string
new ListProperty<string, DateTime?>(someList2); // nullable value type: DateTime?
new ListProperty<string, DateTime>(someList3); // non-null value type: DateTime
如果你想阻止最后一次使用 ,我认为在类声明中对TValue
的约束是不可能的。但您可以通过添加如下静态构造函数来创建检查运行时:
static ListProperty()
{
if (default(TValue) != null)
throw new ArgumentException("Type argument must allow null", "TValue");
}