我有一个类,
public class Revex
{
public IEnumerable<char> AllCharacters = Enumerable.Range(0, 256).Select(Convert.ToChar).Where(c => !char.IsControl(c)).ToArray();
// ...
如果我用
初始化它var r = new Revex { AllCharacters = "abcd" };
以上行是否会被执行(Enumerable.Range ...)?当我以这种方式构建课程时,如果我希望它 not 被调用,我该怎么做?
我有大约10个这样的可选字符类,所以我不想为它们的每个可能组合编写构造函数。
答案 0 :(得分:2)
这样的初始化成员变量总是在构造函数中执行代码之前初始化。
在这种情况下,您有以下顺序
AllCharacters
成员变量AllCharacters
如果要避免此序列,则需要将AllCharacters
的初始化移动到构造函数中。
如果您还想允许可能的覆盖,则可能需要以下内容:
public class Revex
{
public IEnumerable<char> AllCharacters;
public Revex()
: this( Enumerable.Range(0, 256)
.Select(Convert.ToChar)
.Where(c => !char.IsControl(c))
{
// Nothing
}
public Revex(IEnumerable<char> allCharacters)
{
AllCharacters = allCharacters.ToArray();
}
}
12月3日更新
另一种替代方法是仅在类消费者未提供显式值时才使用延迟初始化来提供默认值。您需要切换到公共属性而不是公共字段,并在属性getter中提供逻辑。
public class Revex
{
public IEnumerable<char> AllCharacters
{
get
{
if (mAllCharacters == null)
{
// Default initialization
mAllCharacters
= Enumerable.Range(0, 256)
.Select(Convert.ToChar)
.Where(c => !char.IsControl(c)
}
return mAllCharacters;
}
}
public Revex()
{
// Nothing
}
private IEnumerable<char> mAllCharacters;
}
答案 1 :(得分:2)
此
var r = new Revex { AllCharacters = "abcd" };
是
的语法糖var r = new Revex();
r.AllCharacters = "abcd";
很明显,AllCharacters字段将被初始化为默认值。
如果您不想使用默认值,则可以执行此操作
public class Revex{
public IEnumerable<char> AllCharacters;
public Revex(){
AllCharacters = Enumerable.Range(0, 256).Select(Convert.ToChar).Where(c => !char.IsControl(c)).ToArray()
}
public Revex(IEnumerable<char> allCharacters){
AllCharacters = allCharacters;
}
}
还有一个选项:
public class Regex{
private static IEnumerable<char> DefaultAllCharacters(){ return Enumerable.Range.. }
private IEnumerable<char> allCharacters;
public IEnumerable<char> AllCharacters{
get { return allCharacters ?? (allCharacters = DefaultAllCharacters()); }
set { allCharacters = value; }
}
}
如果尚未设置属性值,则懒惰地初始化该属性值。因此,如果尚未设置值,则不支付设置值的前期成本,但是一旦创建了对象,您就需要支付它。
答案 2 :(得分:1)
如果使用声明初始化类变量,则会进行初始化。因此,在这种情况下,您的字段将被设置两次,一次创建类,然后再设置属性。
如果您希望初始化是可选的,那么您需要将其声明为:
public IEnunerable<char> AllCharacters;
然后,您需要在构造函数中初始化它,或者通过设置属性来完成它。