当我使用slSvcUtil.exe要创建我的服务客户端文件,我看到如下代码:
private string CategoryField;
[System.Runtime.Serialization.DataMemberAttribute()]
public string Category
{
get
{
return this.CategoryField;
}
set
{
if ((object.ReferenceEquals(this.CategoryField, value) != true))
{
this.CategoryField = value;
this.RaisePropertyChanged("Category");
}
}
}
当我检查它时锐锐,我收到以下警告:
'Object.ReferenceEquals' 始终为 false,因为它是使用值类型调用的
我明白那个字符串是不可变的 https://stackoverflow.com/a/4106046/682480,但我似乎收到了每个属性的警告。
锐锐建议如下:
注意:这包括我的自定义样式,将简单的 getter 放在一行上,反转if
,去除多余的object
预选赛和!= true
比较
private string CategoryField;
[DataMember]
public string Category
{
get { return this.CategoryField; }
set
{
if (Equals(this.CategoryField, value)) { return; }
this.CategoryField = value;
this.RaisePropertyChanged("Category");
}
}
所以这确实引出了一个问题,为什么slSvcUtil.exe use ReferenceEquals
代替Equals
if ReferenceEquals
总是会返回 false 吗?
您是否想要使用似乎有争议Equals
or ReferenceEquals
对于字符串。Equals
将比较字符串的值,而ReferenceEquals
将比较引用——但是,由于字符串驻留,等效的字符串文字将作为相同的引用出现。例如:
static void Main(string[] args)
{
string x = "hi", y = "hi", z = string.Concat('h', 'i');
Console.WriteLine(ReferenceEquals(x, y)); // true
Console.WriteLine(ReferenceEquals(x, z)); // false
Console.WriteLine(Equals(x, y)); // true
Console.WriteLine(Equals(x, z)); // true
Console.ReadLine();
}
那么代码生成算法的作者是如何决定的呢?我能想到的几个考虑因素:
- 表现:
Object.Equals
需要虚拟方法调用,这可能比静态方法调用性能低Object.ReferenceEquals
(假设我们正在讨论字符串,作为引用类型不需要装箱)。
-
Normally你会想用
ReferenceEquals
对于引用类型——作者可能认为不值得为字符串的特殊情况维护单独的代码。
- 另请注意,使用
ReferenceEquals
is the 防御性的在这个具体实例中的选择。使用ReferenceEquals
确保 setter 应用于上面的情况#2,而使用Equals
would not在这种情况下应用设置器。您可能会想到一些极端的情况,其中后一种行为可能会引入非常难以检测的错误。
无论如何,Resharper 的警告显然是错误的。String
是引用类型,而不是值类型,并且(如上面的示例所示)ReferenceEquals
事实上可以返回true
对于字符串值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)