[英]How do I use a generic class without specifying its type parameters in C#?
[英]C# - Create an instance of a class with generic type parameters without specifying these types
我有以下代碼:
public static class Typing
{
public static void Run()
{
var type = typeof(GenericSuperType<,>);
type = type.MakeGenericType(typeof(int), typeof(int));
dynamic instance = Activator.CreateInstance(type);
var types = instance.Register();
foreach(var i in types)
Console.WriteLine(i);
}
}
public class GenericSuperType<C, R>
{
public IEnumerable<Type> Register()
{
yield return typeof(MiddlewareOne<C, R>);
yield return typeof(MiddlewareTwo<C, R>);
}
}
public interface IGenericMiddleware<C, R>
{
R Execute(C command);
}
public class MiddlewareOne<C, R> : IGenericMiddleware<C, R>
{
public R Execute(C command)
{
return default;
}
}
public class MiddlewareTwo<C, R> : IGenericMiddleware<C, R>
{
public R Execute(C command)
{
return default;
}
}
我想要實現的是創建一個GenericSuperType<,>
class 的實例,以便調用基本上會返回一些其他泛型類型的Register()
方法。 這樣做的唯一目的是獲取Register()
方法返回的類型(這些類型可能與示例中的類型不同,並且將由用戶在方法重載中提供)。 但是,為了做到這一點,我需要在這里為GenericSuperrType<,>
提供一些類型(就像我對int
所做的那樣),但隨后問題就出現了——這些類型可以對它們有通用約束,比方說:
public class GenericSuperType<C, R> where C : ISomeType
{
public IEnumerable<Type> Register()
{
yield return typeof(MiddlewareOne<C, R>);
yield return typeof(MiddlewareTwo<C, R>);
}
}
在這種情況下,創建任何類型的實例都會失敗。
到目前為止,我嘗試的是檢查C
和R
的通用約束並采取相應的行動,類似於這些行(一個簡單的例子):
public static void Run()
{
var type = typeof(GenericSuperType<,>);
var defparams = type.GetGenericArguments();
IList<Type> typeConstraints = new List<Type>();
foreach (var i in defparams)
{
typeConstraints.Add(i.GetGenericParameterConstraints().FirstOrDefault());
}
for (int i = 0; i < typeConstraints.Count; i++)
{
if (typeConstraints[i] == null)
typeConstraints[i] = typeof(String);
}
type = type.MakeGenericType(typeof(int), typeof(int));
dynamic instance = Activator.CreateInstance(type);
var types = instance.Register();
foreach(var i in types)
Console.WriteLine(i);
}
這可以正常工作,但我必須涵蓋所有可能的通用約束。
我想到的另一件事是:通過反射實際刪除GenericSuperType<,>
泛型類型約束(如果實際上可能,我認為應該這樣做,但我不擅長 c# 反射),然后只提供一些虛擬類型從Register()
方法中獲取類型。 或者也許只是將類型/類/文件的內容復制到另一個沒有泛型類型約束並調用它們? 我正在尋找解決方案(我知道這聽起來很復雜,但我也知道反射是一個強大的工具,可以讓這成為可能)。
預先感謝您的所有幫助!
你的目標到底是什么? 最終,我會說你應該創建一個界面:
public interface IRegster
{
IEnumerable<Type> Register();
}
然后讓你所有的 class 具體實現這個。 然后您不必擔心任何泛型類型或創建虛擬實例或類似的東西。 您只需通過接口獲取類型。
但是,您並沒有真正說明這些泛型類型類稍后將如何最終實例化(真正的實現),所以我不知道任何人都可以在這里給您完美的建議。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.