2

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

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>

更多:我想要这个的原因是要知道该Value属性是否已被分配。在没有我要求的情况下执行此操作将涉及必须键入 value as Object,这对我来说很难闻。

4

5 回答 5

3

这是不可能的。C# 可为空的语法T?(大部分)是System.Nullable<T>. 并且System.Nullable不允许T. 这就是为什么您不能应用于?可能是引用类型的(通用)类型。但是,您可以限制TValuestruct

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

于 2012-07-13T18:36:43.653 回答
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 {
}
于 2012-07-13T18:37:45.240 回答
1

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

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

}
于 2012-07-13T18:40:00.417 回答
1

简单而简短:因为你需要在不同的地方实例化不同的版本,为什么不呢?

ListProperty<SomeListItemType, SomeReferenceType>

ListProperty<SomeOtherListItemType, SomeValueType?>

在适当情况下?但也许我有什么问题...

于 2012-07-13T18:44:22.873 回答
0

我不确定我是否理解您的问题,但就您现在的班级而言,您可以使用任何类型 for 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

如果你想阻止 last use onlyTValue ,我认为在类声明中使用约束是不可能的。但是您可以通过添加这样的静态构造函数来进行检查运行时:

static ListProperty()
{
  if (default(TValue) != null)
    throw new ArgumentException("Type argument must allow null", "TValue");
}
于 2012-07-13T20:41:17.647 回答