我昨天和朋友一起吃午饭,他们null在C#中抱怨.他说那null是不合逻辑的.我决定测试他的说法,所以我测试了一些简单的逻辑命题:
Console.WriteLine(null == null); //True
//Console.WriteLine(null == !!null); //BOOM
Console.WriteLine(10 >= null); //False
Console.WriteLine(10 <= null); //False
Console.WriteLine(!(10 >= null)); //True
Console.WriteLine(!(10 <= null)); //True
Run Code Online (Sandbox Code Playgroud)
检查平等似乎很简单,这就是我所期望的.然而,更多/更少的陈述是逻辑矛盾,我觉得这真的很混乱!这些不应该抛出?否定操作会像您期望的那样抛出.
如果我尝试null在Ruby或Python中运行比较(除了相等),我会得到一个类型错误:"无法将数字与nil进行比较".为什么C#不这样做?
EJo*_*ica 13
好问题.
尽量不要将其null视为具体的价值,而是"在这里看不到任何东西".该文档定义null为
的
null关键字是表示一个空引用,一个不指向任何对象文字.
考虑到这一点,null不是一个对象的事实意味着经典的思想规律并不完全适用于它(或者,至少,它不适用于它应用于实际对象的方式).
话虽这么说,事实上,10 >= null并且10 <= null两者都false严格来说并不是矛盾 - 毕竟,null实际上并非一无所获.如果你说10 >= (some actual thing)并且10 <= (some actual thing)都是假的,那么显然这是矛盾的,但如果没有一些实际的对象,你就不能在经典意义上产生矛盾.亚里士多德从形而上学中对法律的定义如下:
同一个东西既不属于同一个对象又不属于同一个对象,也可能属于所有其他可能的规范,这些都是不可能的,让它们被添加以满足当地的反对意见......
所以,从某种意义上说,我们在这里有一点"漏洞".至少亚里士多德制定了"不矛盾法",它特指的是对象.当然,在这一点上,对"非矛盾法"有多种解释.
现在,转向的情况10 + null.我们可以说这就像null + 10它更容易一样.从某种意义上说,在这一点上应该发生什么 - 应该null"吞噬"10,或者我们应该只说"10 +(什么都没有)真的应该等于10"?说实话,从逻辑的角度来看,我没有一个非常有说服力的答案,而是说"嗯,这是一种设计选择".我怀疑语言设计者要区分10 + null从10 + 0,但我没有文件证明.(实际上,如果它们是相同的话会有点奇怪;毕竟,0是一个可以从自然数构造的实际值,但是null"无论什么价值都没有").
Tig*_*ran 10
我知道它在语言规范的某个地方,这不是我有兴趣知道的.我有兴趣理解为什么这些逻辑违规似乎存在,或者我对逻辑规律的理解是不正确的.
编程语言不应该遵循哲学隐含的逻辑规则,无论如何,编程语言意味着解决具体的行业/业务相关问题.许多语言甚至不遵守数学思维规则,如代数表达式,范畴理论等等,所以......
10必须大于或小于null ...不应该吗?
不,"null关键字是表示空引用的文字,不引用任何对象的文字",并且根据C#规则,编译器扫描所提供类型的可用运算符,如果其中一个参与者是null,则表达式的结果将是null.
寻找提升的运营商
10 + null如何才能为null?
往上看.
如果您不认为“空”是一个值,它会有所帮助 - 它是一个虚无或缺乏值的概念。不仅仅是 C# - 您还会在 SQL 中遇到同样的情况(NULL + 'asdf' 将导致 NULL。)
所以像 (NULL < 10) 这样的东西本身并没有什么逻辑意义——你正在将虚无的概念与实际数字进行比较。从技术上讲,不,虚无不小于 10。它也不大于 10。这就是为什么它在这两种情况下都会返回 false。
警告您远离 NULL 的原因与逻辑无关。下面是一个很好的例子,说明了为什么 C# 中的 NULL 通常会导致 bug/错误:
private NumericalAnalysis AnalyzeNumber(int someValue)
{
if (someCondition)
return null;
return new NumericalAnalysis(someValue);
}
Run Code Online (Sandbox Code Playgroud)
...好吧,现在我们可以调用AnalyzeNumber() 并开始使用NumericalAnalysis:
NumericalAnalysis instance = AnalyzeNumber(3);
if (instance.IsPrime)
DoSomething();
Run Code Online (Sandbox Code Playgroud)
... 哎呀!你刚刚遇到了一个错误。您调用了AnalyzeNumber(),但在使用它之前没有检查返回值是否为null。毕竟,AnalyzeNumber() 有时会返回空值 - 因此当调用 instance.IsPrime 时,它会崩溃。实际上,每次调用该函数时,您都必须执行“if (myVar == null)”检查- 如果您忘记了,您只是引入了一个错误。
| 归档时间: |
|
| 查看次数: |
1946 次 |
| 最近记录: |