注意:我在这里使用.NET 3.5。
假设我有以下构造函数的示例基类/子类:
public Person(string name, int age, string job, bool isMale)
{
Name = name;
Age = age;
Job = job;
IsMale = isMale;
}
public CollegeStudent(string name) : this(name, 18) {}
public CollegeStudent(string name, int age) : this(name, age, "Student") {}
public CollegeStudent(string name, int age, string job) : this(name, age, job, true) {}
public CollegeStudent(string name, int age, string job, bool isMale) : base(name, age, job, isMale) {}
编译器是否足够聪明,可以看到子构造函数正在做的唯一事情是相互链接并最终只是调用基础构造函数?那么,它可以只更改“this”构造函数初始值设定项,以便在编译时直接调用基础构造函数吗?
所以它本质上会改变所有内容:
public CollegeStudent(string name) : base(name, 18, "Student", true) {}
public CollegeStudent(string name, int age) : base(name, age, "Student", true) {}
public CollegeStudent(string name, int age, string job) : base(name, age, job, true) {}
public CollegeStudent(string name, int age, string job, bool isMale) : base(name, age, job, isMale) {}
我想编写类似于第一部分的构造函数,因为它很方便,但是我可能只是为每个构造函数直接调用基础构造函数,如果我只是会产生无用的开销。
答案 0 :(得分:6)
C#编译器将沿着链式构造函数的行向后移动,直到它到达Object
的构造函数。我不认为在链接构造函数方面有很多优化,因为您正在使用它们。为了了解自己,您可以尝试编译该代码,然后使用Reflector来查看优化代码。
在那之前,我等待Jon Skeet。
修改强>
我刚将这个简单的代码编译成一个类(.Net 3.5):
namespace Person {
public class Person {
private String Name;
private int Age;
private String Job;
private Boolean IsMale;
public Person(string name, int age, string job, bool isMale) {
Name = name;
Age = age;
Job = job;
IsMale = isMale;
}
}
public class CollegeStudent : Person {
public CollegeStudent(string name) : this(name, 18) { }
public CollegeStudent(string name, int age) : this(name, age, "Student") { }
public CollegeStudent(string name, int age, string job) : this(name, age, job, true) { }
public CollegeStudent(string name, int age, string job, bool isMale) : base(name, age, job, isMale) { }
}
}
使用Reflector,我发现C#编译器没有按照你建议的方式优化任何构造函数。
答案 1 :(得分:5)
如果有什么要优化它,它应该是JIT编译器,而不是C#编译器。特别是,如果从不同的程序集中调用它,则C#编译器不能假定CollegeStudent中的代码在执行时与编译时的代码相同。
正如SimpleCoder和Jim所说,你不应该太担心这一点。它是重要的性能问题的可能性很小。
正如Mahesh所说,使用C#4,您可以使用带有可选参数的单个构造函数,但是您应该知道,即使您针对.NET 2.0或.NET 3.5,任何人编译反对您的代码使用C#2或C#3编译器将无法使用某些参数是可选的这一事实,并将被强制指定所有参数。
答案 2 :(得分:3)
如果您使用的是C#4.0,请使用可选参数,这些参数更方便,也更简洁。
public Person(string name, int age = 18, string job = "Student", bool isMale = true)
{
Name = name;
Age = age;
Job = job;
IsMale = isMale;
}
现在你可以使用,
public CollegeStudent(string name) : base(name) {}
public CollegeStudent(string name, int age) : base(name, age) {}
public CollegeStudent(string name, int age, string job) : base(name, age, job) {}
public CollegeStudent(string name, int age, string job, bool isMale)
: base(name, age, job, isMale) {}
答案 3 :(得分:2)
我不知道编译器是否足够智能,以消除构造函数相互链接的“无用开销”。但它真的重要吗?你必须问自己的问题是,通过编写第二个版本可能节省的几微秒是否真的值得维护成本。你真的会做那么多的构造函数调用,每次调用那几微秒都很重要。一点都没有?
答案 4 :(得分:1)
您是否了解新语法:
CollegeStudent student = new CollegeStudent
{
Name = "Bob",
Age = 21,
Job = "Spaceman",
IsMale = true,
};
这样的构造函数现在应该是不必要的,除非你必须在旧版本的Visual Studio中编译。