C# 从字符串变量中获取类型并在泛型方法中使用它
C# Getting Type out of a string variable and using it in generic method
我希望能够通过某种方式(即从数据库)获取我收到的字符串值的实际类型,以便我可以在 DoSomething<Type>()
.
等通用方法中使用该类型
在我的项目中,我有 classes Plane
,并且 Car
位于 MyCompany.MySolution.Vehicle
命名空间中,就像这样
- MyCompany.MySolution.Vehicle
|+Interfaces
|-Implementations
|-Car
|-Plane
我收到车辆类型的字符串。所以,我得到了字符串 "Car" 这意味着,我需要得到类型 Car
这样我就可以在通用方法中使用该类型来像这样注册它:
MyFactory.Register<Car>(carId)
因此,MyFactory 是静态的 class 调用 Register() 方法。
同样,我收到字符串 "Plane",这意味着我需要获取类型 Plane
,以便我可以在上面的通用方法中使用该类型来注册一个 Plane。
我尝试使用类似
的东西
MyFactory.Register<Type.GetType("MyCompany.MySolution.Vehicle.Implementations.Car")>(carId)
,但这不起作用。
如果你想在运行时调用带有类型参数生成的通用方法,你可以做这样的事情:
var vehicleString = "Car";
// use the fully-qualified name of the type here
// (assuming Car is in the same assembly as this code,
// if not add a ", TargetAssemblyName" to the end of the string)
var vehicleType =
Type.GetType($"MyCompany.MySolution.Vehicle.Implementations.{vehicleString}");
// assuming MyFactory is the name of the class
// containing the Register<T>-Method
typeof(MyFactory).GetMethod("Register")
.MakeGenericMethod(vehicleType)
.Invoke(this);
请注意:
这不是应该如何使用泛型。我只是指出可能性,并没有给你提出的问题一个理想的答案。也许您应该重新考虑您的一些架构设计选择!
如果Register<T>
做这样的事情
void Register<T>(int id)
{
_dictionary.Add(typeof(T), ...);
}
创建非泛型重载
void Register(Type t, int id)
{
_dictionary.Add(t, ...);
}
这个新的重载不是类型安全的,但是从字符串创建类型无论如何都不是。
泛型的目的是在保持类型安全的同时获得可变性(不要与动态行为混淆!)。但是,当类型在运行时确定时,类型安全性就没有给出,泛型就成了障碍而不是有用。
请注意,类型安全是由编译器确保的,当然它在运行时不起作用。
你可以使用一个字典来保存你所有类型的字符串键:
var d = new Dictionary<String,Type>();
d.Add("Car",typeof(Car));
d.Add("Plane",typeof(Plane));
然后如果你从数据库中得到字符串"Car"你可以得到这样的类型:
var myType = d["Car"];
然后使用myType
作为真正的Type。
我希望能够通过某种方式(即从数据库)获取我收到的字符串值的实际类型,以便我可以在 DoSomething<Type>()
.
在我的项目中,我有 classes Plane
,并且 Car
位于 MyCompany.MySolution.Vehicle
命名空间中,就像这样
- MyCompany.MySolution.Vehicle
|+Interfaces
|-Implementations
|-Car
|-Plane
我收到车辆类型的字符串。所以,我得到了字符串 "Car" 这意味着,我需要得到类型 Car
这样我就可以在通用方法中使用该类型来像这样注册它:
MyFactory.Register<Car>(carId)
因此,MyFactory 是静态的 class 调用 Register() 方法。
同样,我收到字符串 "Plane",这意味着我需要获取类型 Plane
,以便我可以在上面的通用方法中使用该类型来注册一个 Plane。
我尝试使用类似
的东西MyFactory.Register<Type.GetType("MyCompany.MySolution.Vehicle.Implementations.Car")>(carId)
,但这不起作用。
如果你想在运行时调用带有类型参数生成的通用方法,你可以做这样的事情:
var vehicleString = "Car";
// use the fully-qualified name of the type here
// (assuming Car is in the same assembly as this code,
// if not add a ", TargetAssemblyName" to the end of the string)
var vehicleType =
Type.GetType($"MyCompany.MySolution.Vehicle.Implementations.{vehicleString}");
// assuming MyFactory is the name of the class
// containing the Register<T>-Method
typeof(MyFactory).GetMethod("Register")
.MakeGenericMethod(vehicleType)
.Invoke(this);
请注意:
这不是应该如何使用泛型。我只是指出可能性,并没有给你提出的问题一个理想的答案。也许您应该重新考虑您的一些架构设计选择!
如果Register<T>
做这样的事情
void Register<T>(int id)
{
_dictionary.Add(typeof(T), ...);
}
创建非泛型重载
void Register(Type t, int id)
{
_dictionary.Add(t, ...);
}
这个新的重载不是类型安全的,但是从字符串创建类型无论如何都不是。
泛型的目的是在保持类型安全的同时获得可变性(不要与动态行为混淆!)。但是,当类型在运行时确定时,类型安全性就没有给出,泛型就成了障碍而不是有用。
请注意,类型安全是由编译器确保的,当然它在运行时不起作用。
你可以使用一个字典来保存你所有类型的字符串键:
var d = new Dictionary<String,Type>();
d.Add("Car",typeof(Car));
d.Add("Plane",typeof(Plane));
然后如果你从数据库中得到字符串"Car"你可以得到这样的类型:
var myType = d["Car"];
然后使用myType
作为真正的Type。