0

可能重复:
最佳实践:在构造函数或声明中初始化类字段?

这只是我和我的朋友在谈论我们当前的项目时提出的一个简单甚至有点愚蠢的疑问。

我想知道的是调用方法在使用 C# 的类的构造函数内部和外部设置变量之间的区别,如下例所示:

情况1:

public class Test
{
    string myVar = GetValue();

    public Test()
    {
    }
}

案例二:

public class Test
{
    string myVar;

    public Test()
    {
        myVar = GetValue(); 
    }
}

使用这些方法时是否存在性能差异或任何“模式违规”?如果有人能告诉我这些方法中哪一种更好,以及当我在编译器级别使用它们时会发生什么,我将不胜感激。

提前致谢!

4

4 回答 4

1

AFAIK 唯一的区别是首先触发字段初始化(您的第一个示例) - 它本质上仍被视为构造函数代码。通过选择一个而不是另一个没有性能提升,这实际上是一个偏好问题。

要注意的一件事是执行顺序,因为它可以根据您的类层次结构进行更改。

于 2013-01-09T12:07:37.640 回答
1

如果您的方法GetValue是类中的静态方法,那么您可以在字段初始化中使用它。如果它是一个实例方法,你会得到一个错误。

您的第一个代码使用字段初始化,而在您的第二个代码中,您正在初始化构造函数中的字段。

字段 C#

在调用对象实例的构造函数之前立即初始化字段,因此如果构造函数分配字段的值,它将覆盖在字段声明期间给出的任何值。

至于哪个更好,我会说这取决于您的要求。通常,如果您将某些参数传递给要分配给某个字段的构造函数,那么您只能在构造函数中执行此操作。但是,如果您想为字段设置一些默认值,那么在执行构造函数之前,最好有字段初始化器。

于 2013-01-09T12:11:37.743 回答
0

下一种情况是字段初始化可能可行并获得可读性的情况

class Test
{
    string myVar;
    string anotherVar;

    public Test()
    {
        myVar = "one default";
        anotherVar = "another default";
    }
    public Test(string s) //: this()
    {
        myVar = s;
        anotherVar = "another default";
    }
}

您可能不想默认调用构造函数,因为在某些情况下两次初始化某个变量可能是错误的(在我的情况下,它绝对可以);因此,在上面的示例中,我将anotherVar转到字段初始化。

注意:谈到性能,我不在这样的纳米优化级别上 - 当您使用字段初始化时,您的字段会根据需要接收第一个值。当你从构造函数初始化它时,它已经有了它的默认值,所以从技术上讲,你分配了一个字段两次。但是这个惩罚是如此之小,以至于我无法想象它是合理的场景。

于 2013-01-09T12:18:34.620 回答
0

你发布的代码没有编译,所以我继续做了几个可能的变化。

1.静态字段和静态方法

public class Test
{
    static string myVar = GetValue();

    public Test()
    {
    }

    static string GetValue()
    {
        return String.Empty;
    }
}

在这种情况下,在哪里设置静态字段并不重要:在静态构造函数中(代码中未显示)或作为静态字段初始化。当一个类型被加载到 AppDomain 中时,CLR 将初始化两者。(有一个序列,例如 CLR 首先调用静态构造函数,然后设置所有静态字段反之亦然 - 虽然这个序列不在您的控制范围内)。

2. 在构造函数中设置属性

public class Test1
{
    string MyVar{get;set;}
        
    public Test1()
    {
        MyVar = GetValue();
    }

    string GetValue()
    {
        return String.Empty;
    }
}

这取决于类型和用途。在这种特殊情况下,我可能会避免这样做,因为构造函数意味着轻量级。如果您进行任何繁重的处理,最好将其移至Initialize具有适当错误处理和try-catch块的方法。如果您不做任何繁重的工作来设置属性 - 只需在构造函数中放置一个默认值,例如MyVar = "EMPTY".

3.在另一个类中设置属性

public class Test
{
    public string MyVar{get;set;}
        
    public Test(){ }

    public string GetValue()
    {
        return String.Empty;
    }
}

//somewere else 
Test t = new Test();
t.MyVar = t.GetValue();

这看起来有点奇怪,因为类提供了一个状态(属性)和获取当前状态的方法(GetValue 方法)。在这种情况下,两个成员(属性和方法)可能应该合并为一个getter

于 2013-01-09T12:26:18.333 回答