C# - 检查变量是否已初始化

时间:2012-09-13 20:03:36

标签: c# initialization

我想检查变量是否在运行时以编程方式初始化。为了减少这种不太神秘的原因,请参阅以下不完整的代码:

string s;

if (someCondition) s = someValue;
if (someOtherCondition) s = someOtherValue;

bool sIsUninitialized = /* assign value correctly */;

if (!sIsUninitialized) Console.WriteLine(s) else throw new Exception("Please initialize s.");

完成相关位。

一个hacky解决方案是使用默认值初始化s:

string s = "zanzibar";

然后检查它是否发生了变化:

bool sIsUninitialized = s == "zanzibar";

但是,如果someValuesomeOtherValue恰好是“zanzibar”呢?然后我有一个bug。有更好的方法吗?

8 个答案:

答案 0 :(得分:15)

如果编译器知道某个变量尚未初始化,则代码甚至不会编译。

string s;
if (condition) s = "test";
// compiler error here: use of unassigned local variable 's'
if (s == null) Console.Writeline("uninitialized");

在其他情况下,如果某个变量可能尚未初始化,则可以使用default关键字。例如,在以下情况中:

class X
{ 
    private string s;
    public void Y()
    {
        Console.WriteLine(s == default(string));  // this evaluates to true
    }
}

documentation表示默认(T)将为引用类型提供null,为值类型提供0。正如评论中指出的那样,这与检查null非常相似。


这一切都掩盖了这样一个事实:你应该在第一次声明变量时将变量初始化为null或其他什么。

答案 1 :(得分:8)

使用C#2.0,您可以使用Nullable运算符,为以前的值类型设置初始值null,允许执行以下操作:

int? x = null;

if (x.HasValue)
{
    Console.WriteLine("Value for x: " + num.Value); 
}

哪个收益率: “x的值:无效”。

答案 2 :(得分:4)

默认情况下只指定null,而不是字符串值

答案 3 :(得分:3)

这是一种方式:

string s;
if (someCondition) { s = someValue; }
else if (someOtherCondition) { s = someOtherValue; }
else { throw new Exception("Please initialize s."); }

Console.WriteLine(s)

这可能更适合检查字符串是否为null,因为someValue可能有时会返回null。换句话说,null可能是将字符串初始化为的合法值。

我个人比isInitialized旗更喜欢这个。为什么要引入额外的标志变量,除非你必须?我不认为它更具可读性。

答案 4 :(得分:2)

您可以保留一个单独的标志,指示该字符串已初始化:

string s = null;
bool init = false;
if (conditionOne) {
    s = someValueOne;
    init = true;
}
if (conditionTwo) {
    s = someValueTwo;
    init = true;
}
if (!init) {
    ...
}

这将处理分配s的情况,包括分配null,空字符串或"zanzibar"时的情况。

另一个解决方案是创建一个静态字符串来表示“未初始化”值,并使用Object.ReferenceEquals代替==来检查它是否已更改。但是,bool变量方法更明确地表达了您的意图。

答案 5 :(得分:1)

我同意 Vytalyi 的观点,即应尽可能使用默认值 null,但是,并非所有类型(如 int)都可以为 null。您可以按照 David W 的解释将变量分配为可空类型,但这可能会破坏大型代码库中的大量代码,因为在访问之前必须将可空类型细化为其原始类型。

这个通用方法扩展应该有助于那些处理大型代码库的人,其中主要设计决策已经由前任做出:

public static bool IsDefault<T>(this T value) 
        => ((object) value == (object) default(T));

如果你是从头开始,就利用可空类型并将其初始化为空;实现 C# 功能是有原因的。

答案 6 :(得分:0)

我选择了永远无法使用的初始化值,典型值包括String.Emptynull-1和256个字符的随机字符串生成器。

答案 7 :(得分:-1)

通常,将默认值指定为nullString.Empty。对于你不能使用那些&#34;空&#34;值,定义一个常量来表示特定于应用程序的未初始化值:

const string UninitializedString = "zanzibar";

然后,只要您想初始化或测试初始化​​,就引用该值:

string foo = UnininitializedString;
if (foo == UninitiaizedString) {
  // Do something
}

请记住,字符串是C#中的不可变常量,因此实际上只有UninitializedString的一个实例(这就是比较有效的原因)。