在我可以安全地应用像qazxsw poi,qazxsw poi等方法之前,测试qazxsw poi的所有字符串是非常烦人的...
如果null
的默认值是空字符串,我就不必测试,我觉得它与ToUpper()
或StartWith()
等其他值类型更加一致。另外string
会有意义。
那么为什么C#的设计者选择使用int
作为字符串的默认值?
注意:这与double
有关,但更侧重于为什么而不是如何处理它。
为什么字符串的默认值为null而不是空字符串?
因为Nullable<String>
是引用类型,所有引用类型的默认值是null
。
在我可以安全地应用ToUpper(),StartWith()等方法之前,测试我的所有字符串是非常烦人的...
这与引用类型的行为一致。在调用实例成员之前,应该对空引用进行检查。
如果string的默认值是空字符串,我就不必测试了,我觉得它与其他值类型(例如int或double)更加一致。
将默认值分配给this question以外的特定引用类型会使其不一致。
另外
string
会有意义。
null
使用值类型。值得注意的是,null
没有在原来的Nullable<String>
上引入,所以如果他们改变了这条规则就会有很多破碎的代码。(礼貌Nullable<T>
)
也许如果您在分配字符串变量时使用null
运算符,它可能会对您有所帮助。
null
String是一个不可变对象,这意味着当给定值时,旧值不会从内存中消失,而是保留在旧位置,并将新值放在新位置。因此,如果Nullable
的默认值是??
,那么当它被赋予第一个值时,它会浪费string str = SomeMethodThatReturnsaString() ?? "";
// if SomeMethodThatReturnsaString() returns a null value, "" is assigned to str.
块在内存中。
尽管看起来微不足道,但在使用默认值String a
初始化大量字符串时,它可能会变成一个问题。当然,如果这是一个问题,你总是可以使用可变的String.Empty
类。
由于string是引用类型,因此引用类型的默认值为null。
也许String.Empty
关键字让你困惑,因为它看起来与任何其他值类型声明完全一样,但它实际上是String.Empty
中的StringBuilder
的别名。
此外,Visual Studio中的深蓝色和小写的第一个字母可能误导为认为它是string
。
Nullable类型直到2.0才出现。
如果在语言的开头有可空类型,那么字符串将是不可为空的字符串?本来可以为空的。但他们无法做到向后兼容。
很多人都在谈论ref-type或者不是ref类型,但是string是一个与众不同的类,并且已经发现解决方案可以实现。
哈比卜是对的 - 因为Nullable
是参考类型。
但更重要的是,每次使用时都不必检查.NET platform。如果有人通过你的函数@jcolebrand引用,你可能应该抛出string
。
这就是事情 - 如果你试图在一个字符串上调用null
,框架会为你抛出一个ArgumentNullException
。请记住,即使您测试null
的参数,这种情况仍然会发生,因为作为参数传递给函数的对象上的任何属性或方法都可以计算为NullReferenceException
。
话虽这么说,检查空字符串或空值是常见的事情,所以他们提供.ToUpper()
和null
就是为了这个目的。
空字符串和空值根本不同。 null表示缺少值,空字符串表示空值。
编程语言对变量的“值”进行假设,在本例中为空字符串,与使用任何其他不会导致空引用问题的值初始化字符串一样好。
此外,如果将句柄传递给该字符串变量到应用程序的其他部分,那么该代码将无法验证您是否故意传递了空白值,或者您忘记填充该变量的值。
另一个会出现问题的场合是字符串是某个函数的返回值。由于string是一个引用类型,并且在技术上可以将值设置为null并且两者都为空,因此该函数在技术上也可以返回null或空(没有什么可以阻止它这样做)。现在,由于存在2个“缺少值”的概念,即空字符串和空值,所有使用此函数的代码都必须进行2次检查。一个用于空,另一个用于null。
简而言之,对于单个状态只有1个表示总是好的。有关empty和nulls的更广泛讨论,请参阅下面的链接。
public static string EmptyNull(this string str)
{
return str ?? "";
}
string str = null;
string upper = str.EmptyNull().ToUpper();
根本原因/问题是CLS规范的设计者(定义语言如何与.net交互)没有定义一种方法,通过该方法,类成员可以指定必须直接调用它们,而不是通过string myString = null;
string result = myString?.ToUpper();
,而不需要调用者执行空引用检查;它也没有提供任何不受“正常”拳击影响的定义结构。
如果CLS规范定义了这样一种方法,那么.net就有可能始终遵循公共对象模型(COM)建立的线索,在该线索下,空字符串引用被认为在语义上等同于空字符串,而对于其他用户定义的不可变类类型,它们应具有值语义,以同样定义默认值。基本上,对于https://softwareengineering.stackexchange.com/questions/32578/sql-empty-string-vs-null-value的每个成员,会发生什么,例如NULL vs Empty when dealing with user input写成像callvirt
。这种方法可以为应该表现得像值的事物提供非常好的语义,但是由于实现问题需要存储在堆上。这种方法最大的困难在于这些类型和String
之间转换的语义可能会有点模糊。
另一种方法是允许定义特殊结构类型,这些类型不是从Length
继承而是具有自定义装箱和拆箱操作(可以转换为/从某些其他类类型转换)。在这种方法下,会有一个类型为[InvokableOnNull()] int String Length { get { if (this==null) return 0; else return _Length;} }
,其行为与现在的字符串一样,以及一个自定义框结构类型Object
,它将包含Object
类型的单个私有字段NullableString
。尝试将String
转换为Value
或String
如果非null则返回String
,如果为null则返回NullableString
。试图转换为Object
,对Value
实例的非空引用会将引用存储在String.Empty
中(如果长度为零,则可能存储null);转换任何其他引用将引发异常。
即使字符串必须存储在堆上,概念上也没有理由说它们不应该像具有非空默认值的值类型一样。将它们存储为保持引用的“普通”结构对于将它们用作类型“字符串”的代码是有效的,但是在转换为“对象”时会增加额外的间接层和低效率。虽然我没有预见.net会在这个晚期添加上述任何一个功能,但未来框架的设计者可能会考虑将它们包括在内。
因为字符串变量是引用,而不是实例。
默认情况下将其初始化为Empty是可能的,但它会在整个板上引入很多不一致的地方。
为什么C#的设计者选择使用null作为字符串的默认值?
因为字符串是引用类型,所以引用类型的默认值是String
。引用类型的变量存储对实际数据的引用。
我们在这种情况下使用NullableString
关键字;
Value
null
是一个default
,所以它是一个引用类型,所以默认值是string str = default(string);
。
str
string
是一个null
,所以它是一个值类型,所以默认值是int str = (default)(int);
。
如果
str
的默认值是空字符串,我就不必测试了
错误!更改默认值不会改变它是引用类型的事实,并且有人仍然可以将引用显式设置为int
。
另外
zero
会有意义。
真实的一点。不允许string
用于任何参考类型更有意义,而是需要null
用于该功能。
那么为什么C#的设计者选择使用
Nullable<String>
作为字符串的默认值?
与其他参考类型的一致性。现在,为什么允许null
参考类型呢?可能让它感觉像是C,尽管这是一个有问题的设计决定,在一种语言中也提供Nullable<TheRefType>
。