29

我想检查变量是否在运行时以编程方式初始化。为了让这个原因不那么神秘,请看以下不完整的代码:

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碰巧也是“桑给巴尔”怎么办?然后我有一个错误。有更好的办法吗?

4

8 回答 8

25

如果编译器知道变量没有被初始化,代码甚至不会编译。

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
    }
}

文档指出 default(T) 将为null引用类型和0值类型提供。正如评论中所指出的,这实际上与检查 null 相同。


这一切都掩盖了这样一个事实,即您应该null在首次声明变量时真正将变量初始化为或其他。

于 2012-09-13T20:05:05.230 回答
11

在 C# 2.0 中,您有 Nullable 运算符,它允许您为迄今为止的值类型设置 null 的初始值,允许执行以下操作:

int? x = null;

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

这会产生:“x 的值:空”。

于 2012-09-13T20:09:34.937 回答
7

只需默认分配它null,而不是字符串值

于 2012-09-13T20:07:40.933 回答
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一面旗帜。除非必须,否则为什么要引入额外的标志变量?我不认为它更具可读性。

于 2012-09-13T20:11:55.123 回答
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可变方法更明确地表达了您的意图。

于 2012-09-13T20:05:49.903 回答
1

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

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

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

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

于 2021-03-24T15:44:45.520 回答
0

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

于 2012-09-13T20:06:43.630 回答
-2

通常,将默认值指定为nullString.Empty。对于不能使用这些“空”值的情况,定义一个常量来表示特定于应用程序的未初始化值:

const string UninitializedString = "zanzibar";

然后在您想要初始化或测试初始化​​时引用该值:

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

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

于 2012-09-13T21:04:31.913 回答