如何在从构造函数调用的初始化方法中设置只读字段?
我确信我在某个地方看到过,我可以通过使用 Init() 方法上方的属性来执行以下操作,该属性告诉编译器只能从构造函数中调用 Init() 方法,从而允许只读字段被设置。我忘记了这个属性叫什么,我似乎无法在谷歌上找到它。
public class Class
{
private readonly int readonlyField;
public Class()
{
Init();
}
// Attribute here that tells the compiler that this method must be called only from a constructor
private void Init()
{
readonlyField = 1;
}
}
I'm sure I've seen somewhere that I can do the following by using an attribute above my Init() method, that tells the compiler that the Init() method must only be called from the constructor, thus allowing the readonly field to be set. I forgot what the attribute is called though, and I can't seem to find it on google.
public class Class
{
private readonly int readonlyField;
public Class()
{
Init();
}
// Attribute here that tells the compiler that this method must be called only from a constructor
private void Init()
{
readonlyField = 1;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
罗伯的回答就是我书中的方法。如果您需要初始化多个字段,可以使用
out
参数来完成:我个人认为这在某些情况下是有意义的,例如当您希望字段为
readonly
但您还希望能够在派生类中以不同方式设置它们(无需通过某些受保护的
构造函数链接大量参数)。但也许这只是我。Rob's answer is the way to do it, in my book. If you need to initialize multiple fields you can do it using
out
parameters:Personally I find this makes sense in certain scenarios, such as when you want your fields to be
readonly
but you also want to be able to set them differently in a derived class (without having to chain a ton of parameters through someprotected
constructor). But maybe that's just me.我能想到的唯一解决方案是从
Init()
方法返回需要分配readonly
字段的值:The only solution I can think of is to return the value from the
Init()
method that thereadonly
field needs to be assigned:不使用 Initialize 方法,而是通过所有其他构造函数继承基本构造函数如何?
即
这可能有点晚了到达原来需要的人,但看起来这将彻底解决问题......而不需要使用任何类型的令人讨厌的反射或输出参数。
Instead of using an Initialize method, how about inheriting a basic constructor through all your other constructors.
i.e.
This may be a little late to reach the original person in need, but it seems like this will cleanly solve the problem... Without the need to use any sort of nasty reflection or out parameters.
贾里德是对的;这是不可能的。我能想到的解决方法是:
Init
方法)。_myField = GetInitialMyFieldValue();
Init
方法,使用out
修改器。如果您有许多字段需要初始化(这些字段依赖于构造函数参数),这可能会很有用。例如Jared is right; this is not possible. The workarounds I can think of are:
Init
method)._myField = GetInitialMyFieldValue();
Init
method, with theout
modifier. This may be useful if you have many fields to initialize, which are dependent on constructor parameters. E.g.这是不可能的。标记有
readonly
的字段只能从构造函数中设置This cannot be done. Fields which are tagged with
readonly
can only be set from the constructor我最终在当前技术(C# 7.x)中所做的是使用值元组系统:
也不是最干净的,但对我来说似乎更干净。
What i ended up doing in current tech (C# 7.x) is use the value tuple system:
Not the cleanest either, But seems cleaner to me.
C# 编译器仅允许您设置只读字段(如果您在内联初始化它们):
或从构造函数初始化它们:
C# compiler only allows you to set readonly fields if you're initializing them inline:
or from the constructor:
仅使用 getter 的初始化属性怎么样(从 C# 6.0 开始)?
How about an initialized property with a getter only (as of C# 6.0)?
我知道这已经晚了,但是如果需要初始化多个字段,那么使用类作为返回值而不是使用 out params 怎么样,有什么缺点吗?恕我直言,这比使用嵌套构造函数更方便、更具可读性。
I know this is late, but what about using a class as a return value instead of using out params if there is a need to initialize multiple fields, are there any drawacks? Imho this is more convenient and more readable than using nested constructors.
我认为如果使用反射就可以了。实际上这对我有用:
这
是 SetVariableByName():
唯一的事情是 readonlyField 是公共的而不是私有的。我知道您可以编辑私有字段,但不确定为什么它对我不起作用!
I think it works if use Reflection. Actually this works for me:
and
this is SetVariableByName():
the only thing is that readonlyField is public not private. I know that you can edit a private field, but am not sure why its not working for me!