[英]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.