- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我看到了一些非常奇怪的东西,我无法解释。我在猜测一些我不熟悉的 C# 边缘情况,或者运行时/发射器中的错误?
我有以下方法:
public static bool HistoryMessageExists(DBContext context, string id)
{
return null != context.GetObject<HistoryMessage>(id);
}
在测试我的应用程序时,我发现它有问题 - 它为我知道我的数据库中不存在的对象返回 true
。所以我停在方法处并立即运行以下命令:
context.GetObject<HistoryMessage>(id)
null
null == context.GetObject<HistoryMessage>(id)
true
null != 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;
}
有趣的是,当将表达式转换为 object
时,比较会被正确计算:
null == (object)context.GetObject<HistoryMessage>(id)
true
null != (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, EquatableIdentifiableObject other)
{
if (ReferenceEquals(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; }
//...
}
这是怎么回事?
最佳答案
==
运算符对您的类型失败,因为您的重载不正确。 ==
运算符可以正常工作,因为它是 object 的
实现的 ==
被使用,而不是 EquatableIdentifiableObject 的
。 GetObject
中,运算符计算正确,因为它不是正在使用的 ==
的 EquatableIdentifiableObject 的
实现。在 C# 中,泛型是在运行时解析的(至少在此处相关的意义上),而不是在编译时解析。请注意,==
是静态的而不是虚拟的。所以类型 T
在运行时解析,但对 ==
的调用必须在编译时解析。在编译器解析 ==
时,它不会知道使用 EquatableIdentifiableObject 的
实现 ==
。由于类型 T 具有此约束:where T : DBObject, new()
,将使用 DBObject 的
实现(如果有)。如果 DBObject
没有定义 ==
,那么将使用第一个定义的基类(直到 object
)的实现。<关于 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
。如果 ==
是一个实例方法,那就没问题了。由于它是一个静态方法,名称 self
有点误导。更好的名称是 o1
和 o2
或类似这条线的名称,这样两个操作数就可以得到更平等的对待。 关于c# - 对于 expr == null 和 expr != null,与 null 的比较结果为真,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37562816/
这个问题在这里已经有了答案: Difference between JSP EL, JSF EL and Unified EL [closed] (2 个回答) 5年前关闭。 前段时间我读过关于“Co
在阅读德州仪器为其 SensorTag 提供的示例代码时我发现了以下代码段。 void SensorTagIO_processCharChangeEvt(uint8_t paramID) {
我正在尝试编写支持简单语法的宏,例如: boo: 3 and foo: go or bar: 4+2 这是我试过的: macro_rules! solr { ($TOPIC:ident : $
有人知道 C 中 if(Expr,Expr) 结构的逻辑含义是什么吗?喜欢: if(lcn = (ULONG)GetLCN(index),lcn) 最佳答案 当您有“,”时,表达式的计算结果为列表中的
我花了几个小时试图让下面的代码工作 PATH="C:\Ben\MyPictures" echo $PATH MY=`expr 2 + 2` 但这不会起作用,因为“expr: c
我尝试将两个数字(实际上这些是某些远程执行命令的输出)分配给 2 个不同的变量,比如说 A 和 B。 当我回显 A 和 B 时,它们显示值: echo $A 809189640755 echo $B
我该怎么做才能使以下工作正常进行? 我需要创建一个接受 Expr 列表并返回 Expr 的函数(Expr 列表 -> Epxr)。 type DataObject() = let data =
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: bash: $[] vs. $(()) $(( expr )) 构造可用于整数 math在 bash 中,例
我很难理解这里的声明: for( int i=0; i< out_length; i++){ int num=i < length_a ? array_a[i] : 0; ... ... 我
我只是好奇。我想知道表达式是否有特定原因 var &= expr 行为方式与不同 var = var && expr. 看起来第一个表达式中的表达式正在执行,而不管 var 上的 false 值。 我
在 bash 中,我不明白为什么第三个命令不正确: [[ 1 -eq 1 ]] # $? is 0 [[ ! 1 -eq 1 ]] # $? is 1 [[ ! ! 1 -
这个问题在这里已经有了答案: Lifetime of temporaries (2 个答案) 关闭 8 年前。 我有一个统计管理器,它通过测量方法执行所需的时间来检查我的应用程序性能。它的用法是这样
我不确定这里是否有人问过这个问题,但我在这里很困惑。我正在读这本很棒的书,名为《Advanced R》,作者为 Hadley Wickham,来自 here . 这里已经描述了一个名为cement的函
我正在通过解析类似 Excel 的公式来生成 sql 请求。 因此,对于给定的公式,我收到以下请求: SELECT IF(COL1='Y', SUM(EXPR),NULL) FROM Table 我没
我看到了一些非常奇怪的东西,我无法解释。我在猜测一些我不熟悉的 C# 边缘情况,或者运行时/发射器中的错误? 我有以下方法: public static bool HistoryMessageExis
我在玩Prefix和 Postfix运算符(分别为 @ 和 //),我遇到了以下问题。 给定以下代码,它们以相同的方式进行评估: Hold[MatrixPlot@Sort@data] // FullF
有没有人在使用 Pandas 时解决了这个 pylint 问题? C:525,59: Comparison to True should be just 'expr' or 'expr is True
我正在尝试制作一个可以按以下方式调用的宏: mactest!(some::Path[1, 2, AnotherName[3, 4]]) 这相当于以下内容: make_result( "some
这两种方法有区别吗? public String toString() { return this.from.toString() + this.to.toString(); } public
我有一个小问题。如果你想测试这里的两个 bash 脚本。这是工作 #!/bin/bash N=40 while [ "$N" -gt 0 ] do echo $N N=`expr $N - 1` do
我是一名优秀的程序员,十分优秀!