[英]Initializing a readonly member variable with a default constructor in C#
我的代码中有一个简单的工厂实现。 我的目标是让构造的对象保留对创建它们的工厂的引用,因此我将它们连接起来类似于:
public class Factory {
public T CreateObject<T>() where T : Foo, new()
{
return new T() {
parent = this
};
}
}
public class Foo {
internal Factory parent;
internal Foo() { }
}
这就像它所读的那样有效,但我一直在想我可能想要那个parent
变量,这样一旦工厂设置它就不能改变它。 但是,如果我将其声明为internal readonly Factory parent;
,那么工厂就不能再在施工时设定它的价值了。
我通常会通过提供一个带参数的构造函数来解决这个问题,但这会杀死通用实现,因为 AFAIK where T: new()
意味着一个无参数的构造函数。
我的 C# 排骨可能只是缺少一些齿轮,但是对于 go 实施这样的事情,最好的方法是什么? (或者最好放弃readonly
并相信代码不会以不安全的方式修改parent
--- NullReferenceException
s会浮现在脑海中---?)
您可以使用反射来设置字段,无论readonly
修饰符如何,这都将起作用:
public class Factory
{
public T CreateObject<T>() where T : Foo, new()
{
T t = new T();
t.GetType()
.GetField("parent", BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(t, this);
return t;
}
}
我不认为你能得到你想要的东西,但你可以创建一个只能分配一次的属性,然后让工厂覆盖它。 但我想用户总是可以用new CreatingFactory
强制覆盖,但我认为这使它变得困难并且至少清楚地表明了你的意图。
您可以执行以下操作。
class Foo
{
private Factory factory;
public Factory CreatingFactory
{
get { return factory; }
set
{
if (factory != null)
{
throw new InvalidOperationException("the factory can only be set once");
}
factory = value;
}
}
}
class Factory
{
public T Create<T>()
where T : Foo, new()
{
T t = new T()
{
CreatingFactory = this
};
return t;
}
}
创建它后,我搜索并找到了一个可能比我更好的答案: Is there a way to set a property only in C#
我不确定这是否正是您想要的,但我想出了一种方法,用Func
替换您的泛型类型参数,该方法显示如何构造Foo
object 并允许您在构造函数中设置父级。
public class Factory {
private Func<Factory, Foo> creator;
public Factory(Func<Factory, Foo> creator) {
this.creator = creator;
}
public Foo CreateObject()
{
return this.creator(this);
}
}
public class Foo {
internal readonly Factory parent;
internal Foo(Factory parent) {
this.parent = parent;
}
}
接着
public void Main() {
Factory myfactory = new Factory(fact => new Foo(fact));
Foo myfoo = myfactory.CreateObject();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.