[英]C# creating another instance of subclass - Reflection?
我正在重新發布一個我剛剛問過的問題,但是由於我認為我造成了一些混亂,所以想以一種更簡潔的方式重新提出這個問題。
我有一個基類:RoomObject。 我有兩個子類:Bed和Table,它們從RoomObject繼承。
我有一個變量currentObject,它的類型為RoomObject,但實際上將保存Bed或Table的一個實例(RoomObject本身不會實例化)。
如何在不知道其完整類型的情況下克隆我的currentObject?
即如果currentObject是一張床,我想使用
currentObject = new Bed(currentObject);
如果currentObject是一個Table,我想使用
currentObject = new Table(currentObject);
我可以通過調用Activator.CreateInstance(currentObject.GetType())使用反射,然后在需要的所有屬性之間進行復制,但這似乎很麻煩。
您應該使用稱為虛擬構造函數的模式或克隆方法 。
向RoomObject
添加一個虛擬方法,該方法返回當前對象的副本:
abstract RoomObject Clone();
現在,在Bed
實現此方法以返回new Bed(...)
,在Table
實現此方法以返回new Table(...)
。 將必要的任何參數傳遞給Bed
和Table
的構造函數,以復制當前對象中的內容。
.NET具有通常用於實現此模式的ICloneable
接口。 這種方法的一個小缺點是Clone
必須返回object
而不是RoomObject
,因此,如果需要RoomObject
,則需要RoomObject
轉換它。
這是關於反射的最好的事情之一:能夠在不讓客戶代碼知道對象是什么類型的情況下創建對象的能力。 有時它可能會變得凌亂,甚至有時會使代碼變慢,但是-如果使用得當,它將使您的代碼更易於管理。
例如,看一看Factory Pattern ,以及如何使用Reflection以及在這里實現
我認為一種解決方案是為所有對象實現ICloneable接口。 這是一些示例代碼:
class RoomObject : ICloneable
{
public abstract object Clone();
}
class Bed : ICloneable
{
public override object Clone()
{
return new Bed();
}
}
class Table : ICloneable
{
public override object Clone()
{
return new Table();
}
}
class Program
{
public static void Main(String[] args)
{
RoomObject ro = /* from some other places*/
RoomObject newOne = ro.Clone() as RoomObject; /* here's what you what */
}
}
取而代之的是,像其他人在回答中所說的那樣,在.NET Framework上實現現成的ICloneable
接口。
由於ICloneable.Clone()
方法返回object
,那么還實現ICloneable
的自定義ICloneable<T>
呢?
public interface ICloneable<T> : ICloneable
where T : class
{
T TypedClone();
}
public class MyCloneableObject : ICloneable<MyCloneableObject>
{
public string Some { get; set; }
public object Clone()
{
MyCloneableObject clone = new MyCloneableObject { Some = this.Some };
}
public MyCloneableObject TypedClone()
{
return (MyCloneableObject)Clone();
}
}
稍后,在您的代碼中...
MyCloneableObject some = new MyCloneableObject();
if(some is ICloneable<MyCloneableObject>)
{
MyCloneableObject myClone = some.TypedClone();
// .. or the standard `Clone()`:
myClone = (MyCloneableObject)some.Clone();
}
同時實現內置接口和自定義接口是一個好主意,因為您的可克隆對象將與可能接受ICloneable
實現的其他庫一起運行。
最后,應該在設計時解決這種情況,而不是使用反射。 我認為如果您不能修改包含ICloneable
wannabe的庫,就應該進行反射。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.