我刚遇到这种情况,我认为这是一个使用默认关键字的好机会。但它没有编译,我想不出为什么。下面的例子说明了我的问题:
public class Test<TDataSource>
{
public IQueryable<TDataSource> DataSource { get; set; }
public bool GetOneOrDefaultResult()
{
var result = DataSource.SingleOrDefault();
return result != default(TDataSource);
}
}
第8行会出现错误(“运算符'=='不能应用于'TDataSource'和'TDataSource'类型的操作数。”)。我认为使用default关键字将消除引用类型和值类型之间的任何比较问题。
添加限制TDataSource到引用类型的通用约束使这段代码编译。
有人可以解释为什么编译器不能解决这个问题吗?只是不够聪明才能看到它会起作用吗?
这是相关的: Can't operator == be applied to generic types in C#?
[编辑] SLaks的答案给了我一些灵感,'=='运算符不起作用,但Equals函数应该。
public class Test<TDataSource>
{
public IQueryable<TDataSource> DataSource { get; set; }
public bool GetOneOrDefaultResult()
{
var result = DataSource.SingleOrDefault();
return result.Equals(default(TDataSource));
}
}
这个编译会正常运行吗?
答案 0 :(得分:6)
您不能假设每种值类型都会覆盖==
运算符。 (即使他们这样做了,也无法使用泛型来调用它;它是一种静态方法)
相反,你应该写
return !(ReferenceEquals((object)result, (object)default(TDataSource))
|| result.Equals(default(TDataSource)));
如果result
为null
(以及引荐类型),则ReferenceEquals
来电将返回true
,因此Equals
将不会被调用并赢得不要扔NullReferenceException
如果TDataSource
是值类型,ReferenceEquals
将比较两个不同的盒装引用(可能恰好包含相同的值,但仍然不同),因此它将传递给{{1调用。