我有以下方法:
public static bool HistoryMessageExists(DBContext context,string ID){ return null != context.Getobject<HistoryMessage>(ID);}
在测试我的应用程序时,我看到它是不正常的 – 它为我知道的不存在于我的数据库的对象返回true.所以我停止了在方法和立即,我跑了以下:
context.Getobject<HistoryMessage>(ID)nullnull == context.Getobject<HistoryMessage>(ID)truenull != context.Getobject<HistoryMessage>(ID)true
Getobject的定义如下:
public T Getobject<T>(object pk) where T : DBObject,new(){ T rv = Connection.Get<T>(pk); if (rv != null) { rv.AttachToContext(this); rv.IsInserted = true; } return rv;}
有趣的是,当将表达式转换为对象时,正确评估比较:
null == (object)context.Getobject<HistoryMessage>(ID)truenull != (object)context.Getobject<HistoryMessage>(ID)false
没有平等的运算符覆盖.
编辑:事实证明有一个 *** 作符超载,这是不正确的.但是,为什么在内部方法通用Getobject中正确评估这个方法,在这种情况下,rv的类型为HistoryMessage.
public class HistoryMessage : EquatableIDentifiableObject{ public static bool HistoryMessageExists(DBContext context,string ID) { var rv = context.Getobject<HistoryMessage>(ID); bool b = rv != null; return b; } public static voID AddHistoryMessage(DBContext context,string ID) { context.InsertObject(new HistoryMessage { ID = ID }); }}public abstract partial class EquatableIDentifiableObject : DBObject,IObservableObject{ public event PropertyChangedEventHandler PropertyChanged; [PrimaryKey] public string ID { get; set; } //...}public abstract partial class EquatableIDentifiableObject{ //... public static bool operator ==(EquatableIDentifiableObject self,EquatableIDentifiableObject other) { if (ReferenceEquals(self,null)) { return ReferenceEquals(other,null); } return self.Equals(other); } public static bool operator !=(EquatableIDentifiableObject self,null)) { return !ReferenceEquals(other,null); } return !self.Equals(other); }}public abstract class DBObject{ [Ignore] protected DBContext Context { get; set; } [Ignore] internal bool IsInserted { get; set; } //...}
这里发生了什么?
解决方法 >如你已经澄清的那样,== *** 作符失败,因为您的重载不正确.>当转换为对象时,== *** 作符正常工作,因为它是被使用的对象的==的实现,而不是EquatableIDentifiableObject.
>在方法Getobject中, *** 作符正确地求值,因为它不是EquatableIDentifiableObject的正在使用的==的实现.在C#泛型中,运行时解析(至少在这里是相关的),而不是在编译时解决.注意==是静态而不是虚拟的.所以类型T在运行时被解析,但是调用==必须在编译时解决.在编译时,当编译器解析==它不会知道使用EquatableIDentifiableObject的==的实现.因为类型T有这个约束:其中T:DBObject,new(),DBObject的实现(如果有的话)将被使用.如果DBObject没有定义==,那么将使用第一个基类的实现(直到对象).
有关EquatableIDentifiableObject的实现的更多评论==:
>您可以替换此部分:
if (ReferenceEquals(self,null)){ return ReferenceEquals(other,null);}
有:
// If both are null,or both are the same instance,return true.if (object.ReferenceEquals(h1,h2)){ return true;}
>更换更有力
public static bool operator !=(EquatableIDentifiableObject self,EquatableIDentifiableObject other){ ...}
有:
public static bool operator !=(EquatableIDentifiableObject self,EquatableIDentifiableObject other){ return !(self == other);}
>为==定义签名的方法略有误导.第一个参数命名为self,第二个命名为other.如果==是一个实例方法就可以了.由于它是一种静态方法,所以名字自身有点误导.更好的名称将是o1和o2或沿着这条线的东西,以便两个 *** 作数在更平等的基础上对待.
总结以上是内存溢出为你收集整理的c# – 对于expr == null和expr!= null,与null的比较计算结果为true全部内容,希望文章能够帮你解决c# – 对于expr == null和expr!= null,与null的比较计算结果为true所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)