C#是静态类型语言,泛型参数在编译时必须确定,不能直接使用一个字符串来指定泛型参数,可以通过反射或者缓存打开窗口的委托来调用泛型方法。
准备:
准备几个测试供后续使用,代码如下:
cs
public class Animal
{
public virtual void Print()
{
}
}
public class Dog : Animal
{
public override void Print()
{
Debug.Log("这是一只狗");
}
}
public class Duck : Animal
{
public override void Print()
{
Debug.Log("这是一只鸭子");
}
}
public class Test : MonoBehaviour
{
void Start()
{
}
public void SummonAnimal<T>() where T : Animal,new()
{
T animal = new T();
animal.Print();
}
}
方案一:
代码如下:
cs
public void CallAnimalByName(string animalClassName)
{
// 获取程序集中的类型
var type = Assembly.GetExecutingAssembly()
.GetTypes()
.FirstOrDefault(t => t.Name == animalClassName &&
t.IsSubclassOf(typeof(Animal)));
if (type != null)
{
// 通过反射调用泛型方法
var method = typeof(Test).GetMethod("SummonAnimal");
var genericMethod = method.MakeGenericMethod(type);
genericMethod.Invoke(this, null);
}
}
在Test的Start方法中调用
cs
void Start()
{
CallAnimalByName("Dog");
}
结果:

方案二:
代码如下:
cs
private Dictionary<string, Action> animalActions = new Dictionary<string, Action>();
// 注册窗口类型
public void RegisterWindow<T>() where T : Animal, new()
{
string animalName = typeof(T).Name;
animalActions[animalName] = () => SummonAnimal<T>();
}
// 通过配置调用
public void CallAnimalByName2(string animalName)
{
if (animalActions.TryGetValue(animalName, out Action action))
{
action();
}
}
在Test的Start方法中调用:
cs
void Start()
{
RegisterWindow<Duck>();
CallAnimalByName2("Duck");
}
结果:
