实例化对象的区别 - C#基础

4

我是一名面向对象编程的初学者,我有一个简单的问题。这两者之间有何不同:

public class Calculation
{
     private _externalObject = new ExternalClass();

     public int FirstParameter {get;set;}
     public int SecondParameter {get;set;}
     public int ThirdParameter {get;set;}
     public int FourthParameter 
     {
          get
          {
               _externalObject.Calculate(FirstParameter, SecondParameter, ThirdParameter);
          }
     }
} 

并且

public class Calculation
{

     private _externalObject;

     public Calculation()
     {
           _externalObject = new ExternalClass();
     }

     public int FirstParameter {get;set;}
     public int SecondParameter {get;set;}
     public int ThirdParameter {get;set;}
     public int FourthParameter 
     {
          get
          {
               _externalObject.Calculate(FirstParameter, SecondParameter, ThirdParameter);
          }
     }
} 

我想学习如何编写最佳代码。

2
https://dev59.com/8nVD5IYBdhLWcg3wTJvF - User 12345678
非常好的问题,欢迎来到SO!另外,请不要忘记接受Oded在下面提供给您的答案。 - Brian
2
在这种情况下,简单来说是没有区别的。 - Omar
2个回答

7
在这种情况下,没有任何可衡量的差异。
但是,如果你有多个构造函数,如果你没有直接在字段声明中初始化该字段,你将不得不在每个构造函数中初始化该字段。
这更多是个人风格的问题。
注:关于类设计和集成——如果你有外部依赖项,好的面向对象编程要求你使用 DI(依赖注入)而不是直接在类中实例化该值。构造函数注入是一个很好的选择:
 private ExternalClass _externalObject;

 public Calculation(ExternalClass externalClass)
 {
       _externalObject = externalClass;
 }

以上内容允许在不改变实际类的情况下修改行为,并使该类更易于测试。

如果你打算进行辅导,最好将其制作成接口。 - bas
@bas - 呃,接口被过度使用了。 - Oded

2
在这种情况下,这两个类是相同的。实际上,对于几乎所有的目的来说,你使用的这两种代码风格是一样的。通常,你会发现大多数风格指南都建议使用字段初始化器(特别是静态字段初始化器)。
有一个微妙的区别,但它很少会影响到你。
每当你在内联初始化类成员时,C# 会生成代码,在运行任何构造函数中的代码之前执行该初始化。特别地,如果你的构造函数调用了基类构造函数。字段初始化器在调用基类构造函数之前运行,而你提供的构造函数中的代码必须在此之后运行。也就是说,以下两个类略有不同:
public class B : A
{
  // This happens *before* the base-class constructor.
  public ExternalObject external = new ExternalObject();

  public B () : base() { }
}

public class C : A
{
  public ExternalObject external;
  public C () : base()
  {
    // This happens *after* the base-class constructor.
    this.external = new ExternalObject();
  }
}

请注意,如果您没有提供默认构造函数,C#会自动为您调用base()提供一个默认构造函数,使您的类“看起来像”类B 即使您没有显式提供B()构造函数也是如此。

实际上,这种差异不太重要。您实际上无法在字段初始化器中引用this,因此无论哪种情况下,您都无法依赖于基类被构造。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接