构造函数内部和外部调用方法的区别[重复]

问题描述 投票:0回答:4

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

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

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

案例1:

public class Test
{
    string myVar = GetValue();

    public Test()
    {
    }
}

案例2:

public class Test
{
    string myVar;

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

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

c# oop constructor instantiation
4个回答
1
投票

据我所知,唯一的区别是首先触发字段初始化(您的第一个示例) - 它本质上仍然被视为构造函数代码。选择其中之一并不会提高性能,这实际上是一个偏好问题。

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


1
投票

如果您的方法

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

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

字段 C#

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

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


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

 移至字段初始化。

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


0
投票
您发布的代码无法编译,所以我继续做了一些可能的变体。

1.静态字段和静态方法

public class Test { static string myVar = GetValue(); public Test() { } static string GetValue() { return String.Empty; } }
在这种情况下,在哪里设置静态字段并不重要:在 

static 构造函数中(代码中未呈现)或作为静态字段初始化。当类型加载到 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

© www.soinside.com 2019 - 2024. All rights reserved.