[英]Returning desired type from Activator.CreateInstance() instead of object
我正在嘗試創建用戶想要的任何指定Type
的實例。 為了快速說明我的目的,請參閱下面的代碼:
static void Main(string[] args)
{
object o = GetInstance(typeof(int));
Console.WriteLine("Created type: {0}", o.GetType().FullName);
}
public static object GetInstance(Type t)
{
Console.WriteLine("Creating instance of {0}", t.FullName);
return Activator.CreateInstance(t);
}
問題是Activator.CreateInstance()
默認返回object
。 此方法還有一個重載,如T Activator.CreateInstance<T>()
,它是無參數的,並返回您指定為T
的類型。
但是,問題是在調用此方法時T
應該是硬編碼的,因此應該是一個固定值。 我正在嘗試創建所需類的實例並將其作為其類型返回。
現在,如果您使用此方法,您應該編寫如下內容:
int i = GetInstance(typeof(int)) as int
我試圖將其減少到:
int i = GetInstance(typeof(int))
有沒有辦法可以在GetInstance
進行強制GetInstance
並將其as int
重復刪除? 通過這種方式,我的返回類型(以及我將對象轉換為的類型)在編譯時將是未知的。
對我來說似乎不可能設計,但如果你能弄清楚,我真的很感激。
編輯:我被卡住的地方是,例如,當你在投射時,如果你在一個通用方法中,你可以做return (T) result
,但你不能做Type t = ...; return (t) result
Type t = ...; return (t) result
這不起作用。 您不能強制轉換為在編譯時作為參數傳遞給您的類型。
這不是一個新問題。 這是任何允許特定類型返回值的 API 所面臨的問題。 例如,像 Newtonsoft 這樣的 JSON 解析庫(即 2019 年 .NET 程序員下載的最流行的 .NET 包)必須能夠解析字符串並返回特定於類型的對象,該對象可能或可能在編譯時不知道。 效仿他們的榜樣可能是有意義的。
Newtonsoft 在反序列化時公開了三種指定類型的方法。 您可以按照目前的方式進行:
//Cast required
var result = JsonConvert.DeserializeObject(text, typeof(MyType)) as MyType;
您可以使用通用方法:
//No cast required, but you have to hardcode a type as a type parameter
var result = JsonConvert.DeserializeObject<MyType>(text);
或者,您可以將實例用作模板,這對於匿名類型非常有用,盡管您也可以將其與非匿名類一起使用。 這個通過泛型類型推斷工作:
//No cast required and no need to specify type; the type is inferred from the argument
var result = JsonConvert.DeserializeAnonymousType(text, new MyType());
這是你的方法:
因此,為了讓您完成這項工作,您的代碼可能如下所示:
public object GetInstance(Type type)
{
return Activator.CreateInstance(type);
}
int i = GetInstance(typeof(int)) as int;
public T GetInstance<T>()
{
return Activator.CreateInstance<T>();
}
int i = GetInstance<int>();
public T GetInstance<T>(T template)
{
return Activator.CreateInstance<T>();
}
int i = GetInstance(0);
如果你這樣做,很難想象任何程序員在使用你的庫時會遇到問題,因為他們應該已經熟悉這種方法。
實際上你可以這樣寫GetInstance
:
static T GetInstance<T>()
{
return Activator.CreateInstance<T>();
}
並使用它:
int j = GetInstance<int>();
這可能會幫助您創建所需類型的實例:
public class ConcreteFactory<T> : AbstractFactory<T>
{
public override T CreateInstance(string typeName,params object[] parameters)
{
var path = Assembly.GetExecutingAssembly().CodeBase;
var assembly = Assembly.LoadFrom(path);
var type = assembly.GetTypes().SingleOrDefault(t => t.Name == typeName);
return (T)Activator.CreateInstance(type, parameters);
}
}
這里的關鍵是泛型類型 T 可用於轉換創建的實例,這可以用作模板來創建具有參數化構造函數的任何類型的實例
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.