C# 如何在内部保留泛型类型参数的始终可为null的等价项?

C# 如何在内部保留泛型类型参数的始终可为null的等价项?,c#,.net,generics,C#,.net,Generics,我认为首先有一个代码示例是必要的。我正在尝试构建一个视图模型,用于所有需要下拉控件的属性,这是一个开始: public class ListProperty<TListItem, TValue> { private readonly string _valuePropertyName = "Id"; private readonly string _textPropertyName = "Name"; public TValue Value { get; s

我认为首先有一个代码示例是必要的。我正在尝试构建一个视图模型,用于所有需要下拉控件的属性,这是一个开始:

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;
    }
}
公共类ListProperty
{
私有只读字符串_valuePropertyName=“Id”;
私有只读字符串_textPropertyName=“Name”;
公共TValue值{get;set;}
私有IEnumerable\u列表;
公共列表属性(IEnumerable列表)
{
_列表=列表;
}
}
我希望
Value
有一个始终可为null的底层属性,因此如果
TValue
是引用类型,底层类型将仅为
TValue
,但是当
TValue
是值类型时,底层类型必须是
null


更多:我之所以要这样做,是想知道
属性是否已分配给。要在没有我的要求的情况下执行此操作,需要将值键入为
对象,这对我来说很难闻。

这是不可能的。C#nullable语法
T?
主要是
System.nullable
的快捷方式。和
System.Nullable
不允许
T
的引用类型。这就是为什么不能将
应用于可能是引用类型的(泛型)类型。但是,您可以将
TValue
限制为
struct


或者,您可以编写自己的
Nullable
helper结构,以允许引用类型。

您可以尝试将它们拆分到不同的类中:

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 {
}
公共抽象类ListProperty{
公共TValue值{get;set;}
...
}
公共类RefListProperty:
ListProperty,其中TValue:class{
}
公共类属性:
ListProperty,其中TValue:struct{
}

我能想到的最好方法是传递三个参数,然后只传递其中一个:

public class ListProperty<TListItem, TValueStruct, TValueClass> 
where TValueStruct : struct
where TValueClass : class
{

}
公共类ListProperty
其中TValueStruct:struct
上课地点:班级
{
}

简单而简短:既然您需要在不同的地方实例化不同的版本,为什么不呢

ListProperty<SomeListItemType, SomeReferenceType>
ListProperty

ListProperty

在适当的地方?但也许我有点不对劲…

我不确定我是否理解您的问题,但就您的类而言,您可以为
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

? 是“Nullable”标志,我忘了放在哪里:-(当你去构造时,很确定它是?t值TValue@MattWestlake:这将是
TValue?
。另外,@ProfK,更改类型通常是个坏主意。一个名为NullableListProperty的新类如何?您是第一个了解我真正问题的人。我将查看一个自定义Nullable,谢谢。
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
static ListProperty()
{
  if (default(TValue) != null)
    throw new ArgumentException("Type argument must allow null", "TValue");
}