& # 39; int # 39;永远不等于null for '变量
本文关键字:for 变量 永远 int 不等于 null | 更新日期: 2023-09-27 17:49:24
有人能回答我这个-为什么我得到这个警告"表达式的结果总是'假',因为类型'int'的值永远不等于'null'类型'int?"
代码
private char classLetter;
public char ClassLetter
{
get { return classLetter; }
set
{
if (classLetter == null)
{
classLetter = value;
RaisePropertyChanged("ClassLetter");
}
else throw new ArgumentOutOfRangeException();
}
}
如果我使用这段代码,没有警告出现
private char classLetter;
public char ClassLetter
{
get { return classLetter; }
set
{
if (classLetter.ToString() == null)
{
classLetter = value;
RaisePropertyChanged("ClassLetter");
}
else throw new ArgumentOutOfRangeException();
}
}
总之,我的问题是
如何为char变量给出int警告?
编辑:'char'应该包含任何拉丁字母或西里尔字母,不允许有特殊符号和数字。如何过滤呢?
在第一种情况下,classLetter
的类型是char
,而CC_2不可能是null
,因为它是一个值类型;它需要是char?
型的。所以比较classLetter == null
是没有意义的,因为编译器说。
在第二种情况下,想象classLetter
是'x'
。当执行classLetter.ToString()
时,您得到"x"
,它可以与null
进行比较,因为它现在是引用类型。但是,这不是你想要的,因为classLetter.ToString()
永远不会是null
。
如果你想只设置一次值,你可以这样做:
private char? classLetter = null; // make it nullable
public char ClassLetter
{
get {
if(classLetter == null) { // if we don't have a value yet
// do something, like throwing an exception
}else{ // if we do have a value already
return classLetter.Value; // here we return char, not char?
}
}
set
{
if (classLetter == null) {
classLetter = value;
RaisePropertyChanged("ClassLetter");
}
else throw new ArgumentOutOfRangeException();
}
}
类型为char
的变量是值变量,而不是引用变量,因此它永远不可能是null
。只有引用类型的变量可以是null
您将得到一个警告,因为值类型永远不会为空。完整的(er)解释如下。
c#中的char
是一个值类型,永远不能为空。考虑char
的目的,即表示一个Unicode字符。在0x0到0xFFFFFFFF范围内,没有一个合适的值来表示null
。(的确,UTF-16实际上并没有涵盖整个范围,但将来可能会。)
对于一个范围小得多的东西来说,这有点容易理解。考虑byte
。取值范围为0 - 255。现在,为了表示null
,我们需要选择一种存储null
的方式。最后出现了一些解决方案:
- 将额外的信息存储到
byte
以表示null。 - 在有效的
byte
范围内选择一个值来代替实际的null
。您最终需要在整个程序中检查此值。在小范围内,这不是问题,但是当您不知道谁将使用您的代码时(很可能是这种情况),您必须记录并希望他们看到。
提供非空值类型和默认值是一个更简单的实现,如果需要,提供一个可以表示null
的值类型的包装器,. net对Nullable<T>
类型和语言支持的快捷方式(int?
, byte?
等)就是这样做的。
如果classLetter
真的可以是char
可以表示的任何值,那么您可以使用:
private char classLetter;
public char ClassLetter
{
get { return classLetter; }
set
{
classLetter = value;
RaisePropertyChanged("ClassLetter");
}
}
你可以这样做,因为如果用户试图对classLetter
做一些他们不可能做的事情,编译器会给用户一个编译时错误。
如果你对classLetter
应该代表什么有额外的要求,更新你的问题,我将更新我的答案。
在回应你对另一个答案的评论时:"我希望行为简单。我希望能够放置任何符号,但我不希望变量为空"
我们需要解决的唯一一件事是"空"的真正含义。在你的语境中,空是什么意思?一旦回答了这个问题,就可以在包含classLetter
的类型中使用默认初始化将其设置为该值。一个一般化的例子:
class Foo {
private char classLetter;
public char ClassLetter {
get { return classLetter; }
set {
classLetter = value;
}
}
public Foo(char classLetter = 'A') {
this.ClassLetter = classLetter;
}
}
当调用者使用new Foo()
时,他们将得到一个Foo
实例,其中Foo.ClassLetter == 'A'
。当然,A
可以是任何合理的默认值,以满足您的特定需求。
这是你想要的吗?
private char? classLetter;
public char ClassLetter
{
get { return classLetter.Value; // this will throw exception, if value hasn't set }
set
{
if (classLetter != null)
{
throw new InvalidOperationException("ClassLetter has been set already.");
}
classLetter = value;
RaisePropertyChanged("ClassLetter");
}
}
注意,ArgumentOutOfRangeException
不适合这种情况。没有对参数的范围进行任何测试。