如何在C#中判断变量是否已经初始化?

24

我知道这是一个愚蠢的问题,而且我猜这个问题以前一定被问过了。然而,我无法找到我的问题的答案。

以下是一些示例代码(当然不能编译),以概述我的问题:

class test
{
     int[] val1;
     string val2;

     static bool somefunction(test x, test y)
     {
         dosomestuff()

         test result;

         while(result is nothing)
         {
              if(somecondition){result=new test(something);}
         }
     }
}
我遇到的问题在以下这行代码中:

The problem which I have is in the following line:

while(result is nothing)

这是VB的语法,当然不是C#编译器接受的。 有人能告诉我如何解决这个问题吗?


1
这并不是一个愚蠢的问题。当我从VB.NET转到C#时,我也遇到了很多类似的情况。 - Mike Cole
7个回答

41
  • 简而言之:

    if (Object.Equals(myVariable, default(MyVariableType)))

    • 替换myVariableMyVariableType

    还有其他解决方案。

if (myVariable == null)无法[1]value types一起使用。请参见下面有关引用类型值类型struct的简短介绍。

值类型主要是struct(例如DateTime),包括[2]simple types,如intenum。值类型本质上不支持null值。

异常和修复方法是可空类型:本质上,这些类型将null添加到结构类型的可能值中。它们在结构上与其他语言中可能已知的Maybe<T>相同[3]。您可以使用ValueType?(例如int?)创建它们,这是Nullable<ValueType>的语法糖。


if (Object.Equals(myVariable, default(MyVariableType)))

这适用于引用类型(对象)和值类型。
请注意,您必须手动替换MyVariableType - 不幸的是您不能执行此操作

if (Object.Equals(myVariable, default(myVariable.GetType())))

因为default()只接受类型名称作为参数。(我猜它在编译时求值。)

结构体简介

简单来说,结构体是精简版的类。想象一下不支持继承或终结器的类,那么你就有了这个精简版:结构体。结构体的定义方式和类相同(除了使用 struct 关键字),除了前面所述的限制外,结构体可以拥有相同丰富的成员,包括字段、方法、属性和运算符。
[引自:http://www.albahari.com/valuevsreftypes.aspx]

类是引用类型:一个类变量(或更具体地说,它的内存区域)仅包含指向另一个内存区域的指针,实际的对象实例数据存储在那里。

值类型变量直接包含数据。这可能会因为 缓存局部性 和节省查找时间而带来速度优势。但在更复杂的结构体情况下,这也可能会对性能产生不利影响。



注释:

[1] 它甚至不会报错。 myVariable == null 总是会返回 false,因为你的 myVariable 将被初始化为非 null 默认 值(零(等效)或一个由零和 null 组成的结构体)。这个默认值可以通过 default(Type) 获得。

[2] 技术上来说,简单类型(除了stringobject之外的所有内置类型都是结构体。顺便提一下:内置类型是System命名空间中的类型别名。

[3] 例如在Haskell中。在C#中,Maybe<T>不是内置类型,但可以实现它。它为类和结构体都提供了Nothing,作为一个更明确/自我说明的null版本。

[4] 没有[4]。真的,你可以去检查。


使用 ? ValueType 是个好提示。 - boutta

24
你要查找的语法是:

你要查找的语法是:

while (result == null)

你还需要设置 result = null; 来开始操作。


10
这将不能适用于值类型。请参考我下面的答案进行修复。 - Aaron Thoma
1
是的,但那不是问题。问题是具体询问了一个名为testclass,它不是值类型。 - Colin Mackay
1
同意,你的答案对于提问者的示例是正确和完整的。我认为指出它并不完全符合问题更一般的标题是有用的;虽然这对我来说似乎并不明显,但对其他遇到这个问题的人来说是相关的。 - Aaron Thoma
我声明了一个类,但没有初始化它。然后如果尝试检查 if(myClass == null),Visual Studio 将不允许我运行此程序。错误是“使用未签名的局部变量”。 - MindRoasterMir

4
while (result == null)

编译器针对此问题抛出以下异常:"使用了未赋值的局部变量 'test'"。 - niklasfi
不,因为我一开始没有像Colin Mackay建议的那样将test=null设置。 - niklasfi
好的。很高兴你能解决它。 - Robert Harvey

3
while (result ==null )

如果我理解正确的话。

2
尽管你已经有了一个满意的答案,但这里有一些你可能会觉得有趣或有帮助的东西。
C#和VB.NET之间存在差异。在VB.NET中,你可以这样写:
```vb Dim x = If(condition, value1, value2) ```
而在C#中,你需要这样写:
```csharp var x = condition ? value1 : value2; ```
Dim b as Boolean

在C#中,您可以编写:

bool b;

它们之间有微妙的区别。在VB.NET中,b已经被赋予了false值(换句话说,它已经被初始化)。而在C#中,b没有值(未初始化)。C#花费了很多力气来确保您不能检查从未初始化的变量的值。
因此,您并不是在测试变量是否已初始化。在VB.NET中,不存在未初始化的变量。在C#中,不可能获取未初始化变量的值以便与任何内容进行比较。
您正在测试变量是否已初始化为nullNothing

1
while(result == null)

在C#中,无值的等价表示是null。


0
while (result == null)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接