我正在尝试设置自定义IDictionary,它将允许Object作为我的TValue.
这是它的样子:
public class NullTolerantDictionary<TKey, TValue>
: Dictionary<TKey, TValue> where TValue : class
{
public TValue this[TKey key]
{
get
{
TValue value;
if (TryGetValue(key, out value))
{
return value;
}
else
{
return DependencyProperty.UnsetValue;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
当编译它时说:
无法将类型'object'隐式转换为'TValue'.
所以为了解决这个问题,我将类型约束更改为:
where TValue : object
Run Code Online (Sandbox Code Playgroud)
(object而不是上课)
然后我收到这条消息:
约束不能是特殊类'对象'
我该如何解决这个问题?
用于解释为什么object不能成为约束的额外功劳.
这里的问题不是泛型类型参数约束,而是索引器的签名.
索引器被记录为始终返回a TValue,无论发生什么.else然而,分支尝试返回DependencyProperty.UnsetValue,这是类型object.由于并非所有objects都是TValues,编译器会抱怨("没有隐式转换").
如果您放置了任意数量的约束TValue,即使您可以约束它,也没有区别object.类型参数仍然可以设置为更多派生的东西object,DependencyProperty.UnsetValue但仍然不能转换为该类型.
如果要实现这样的效果,可以使用public static只读属性,例如
public class NullTolerantDictionary<TKey, TValue>
: Dictionary<TKey, TValue> where TValue : class
{
public static TValue MissingValue { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
并从索引器返回,可能是因为它可以用于参考比较.
但这仍然会留下一个问题:如何实际获得一个TValue价值MissingValue?您可以将new()约束置于TValue静态构造函数中并在其中创建实例,但这会减少此类的可能应用程序.这导致设计开始变得有点笨拙使用,因为这正是你试图避免的那样,没有太多的意义.
为什么对象不能成为约束?我该如何解决这个问题呢?
你没有.你不需要..NET中的所有托管类型都可以转换为object.有一些东西不能(非托管指针等),但它们无论如何都与泛型不兼容.
我猜,真正的问题DependencyProperty.UnsetValue是object.嗯......那不是TValue.想象一下TValue是:int或者byte没有"未设置"的值int或者byte.你不能object为这样的人返回任意的TValue.
坦率地说,我只是让你的调用者TryGetValue直接使用,而不是使用这种扩展方法.你可以做一些事情,比如用a返回一个虚拟类实例TValue,或者返回null- 但坦率地说,调用者可以调用TryGetValue以更方便地实现同样的事情.