为什么在一行中声明一个变量,并在下一行中分配它?

Nik*_*wal 4 .net c# coding-style

我经常在C#代码中看到以下约定:

some_type val;
val = something;
Run Code Online (Sandbox Code Playgroud)

喜欢

DataTable dt;
dt = some_function_returning_datatable();
Run Code Online (Sandbox Code Playgroud)

要么

DataTable dt = new DataTable();
dt = some_function_returning_datatable();
Run Code Online (Sandbox Code Playgroud)

代替

some_type val = something;
DataTable dt = some_function_returning_datatable();
Run Code Online (Sandbox Code Playgroud)

我最初认为这是一个习惯,当你必须在范围顶部声明所有局部变量时.但我已经学会了不要那么快地解雇资深开发者的习惯.

(在我的第3段代码中,当我们dt先分配new然后从函数中分配时,它不会浪费内存)

那么,有一个很好的理由在一行中声明,然后分配吗?

Jon*_*eet 18

在我的第3段代码中,当我们首先使用new然后从函数分配dt时,它不会浪费内存

是的,确实如此.只是相对较小 - 创造一个无用的DataTable对象 - 但仍然浪费不清楚.

那么,有一个很好的理由在一行中声明,然后分配吗?

仅当您没有立即获得该值时.例如:

string x;
if (someCondition) {
    // Do some work
    x = someResult;
} else {
    // Do some other work
    x = someOtherResult;
}
Run Code Online (Sandbox Code Playgroud)

通常可以使用条件运算符或将该代码提取到方法中来改进.虽然有时它不会那么成功.

对于简单的情况:

Foo x = SomeInitializationWithNoUsefulSideEffects();
x = SomeUsefulValue();
Run Code Online (Sandbox Code Playgroud)

要么

Foo x;
x = SomeUsefulValue();
Run Code Online (Sandbox Code Playgroud)

绝对应该重构

Foo x = SomeUsefulValue();
Run Code Online (Sandbox Code Playgroud)

声明点确实有所作为的另一个有趣情况是捕获的变量,尽管通常不是它的预期方式:

int x;
for (int i = 0; i < 10; i++) {
    x = SomeFunction();
    actions.Add(() => Console.WriteLine(x));
}
Run Code Online (Sandbox Code Playgroud)

VS

for (int i = 0; i < 10; i++) {
    int x = SomeFunction();
    actions.Add(() => Console.WriteLine(x));
}
Run Code Online (Sandbox Code Playgroud)

在第一个代码片段中,每个代理都将捕获相同的变量,因此它们都可以有效地查看返回的最后一个值SomeFunction.在第二个片段中,每个代表将捕获一个单独的 "实例" x.

  • @ubercooluk - 没有.投票******不是**用户**.是的,它有正确的改变;),但评估帖子自己的优点. (5认同)

Dar*_*rov 9

但我已经学会了不要那么快地解雇资深开发者的习惯.

很快就解雇他们而不用担心或犹豫不决.用C#编写完全没有意义:

some_type val;
val = something;
Run Code Online (Sandbox Code Playgroud)

代替:

some_type val = something;
Run Code Online (Sandbox Code Playgroud)

要么:

DataTable dt = new DataTable();
dt = some_function_returning_datatable();
Run Code Online (Sandbox Code Playgroud)

代替:

DataTable dt = some_function_returning_datatable();
Run Code Online (Sandbox Code Playgroud)

无论如何,如果你没有在你的代码中忽略它们,C#编译器会在发出生成的IL时忽略它们.

  • @ubercooluk对所提出的内容/答案进行投票,而不仅仅是来自前10名的人回答了它. (2认同)