我创建了一个泛型类,但我知道在运行时类型,而不是在设计,所以我想知道如何设置在运行时的类型。
例如,我有:
public class MyGenericClass<T>
{
....
}
然后,我尝试使用它。 我在其他类中的方法,消耗这个通用类。 在这个类的构造函数,我收到的参数,我想要的类型,所以我必须在我救我需要的类型的类型属性。 所以,我想这一点:
MyGenericClass<_typeNeeded> myClass = new MyGenericClass<typeNeeded>();
但是,这是行不通的。
如何设置,我创建了一个类运行时类型?
我使用C#4.0。
谢谢。 Daimroc。
编辑:我想要做的是以下几点。 我有需要做一些数据库查询的类。 此查询总是返回相同的信息,一类,但却包含了这个类来自不同表中的信息。 这是因为我需要确定的是什么查询使用。 若要决定使用何种查询我用我收到的类型。
就是因为这个原因,我没有在设计上式可知,但在运行时。
我可以使用,这将通过实施以类的接口,并使用具有正确的类实例化的接口,但是这让我有实例化的时刻,如果一个交换机或一个,这就是我尽量避免,我想要的东西更通用。 另外,如果我用这个解决方案,有一个如果instantion的那一刻,我可以创建通用类,所以我就只有一个班,这将是更容易维护。
您可以以另一种方式创建类,传递给构造要使用和利用类型dynamic
关键字。
例如:
class MyGeneralClass
{
dynamic myVariable;
Type type;
public MyGeneralClass(Type type)
{
this.type = type;
myVariable = Activator.CreateInstance(type);
//And then if your type is of a class you can use its methods
//e.g. myVariable.MyMethod();
}
//If your function return something of type you can also use dynamic
public dynamic Function()
{
return Activator.CreateInstance(type);
}
}
看一看在MakeGenericType
方法。 您可以使用它来创建一个Type
实例(然后可以用于创建类型的实例),在运行时确定一般的参数值。 要知道,虽然,你将需要时与该对象的一般特征处理更多的思考; 你不能在代码中创建一个类型为泛型类型变量类型参数变量。
我没有对你的代码足够的信息,但也许你可以使用简单的多态:
public interface IMyInterface
{
...
}
public class MyGenericClass<T> : IMyInterface
{
....
}
IMyInterface myClass = new MyGenericClass<typeNeeded>();
你也可以用工厂设计模式混合这一点,所以,其他一些类将负责基于一些运行您的知识类型的实例。
当然,这假设你MyGenericClass这么想的有这样的方法:
public T GetT(){...}
或者如果它确实存在的所有T'types之间的附加关系,使他们都有共同的超可以说巴塞特,你可以改变
public T GetT(){...}
至:
public BaseT GetT(){...}
如果你想想看,没有理由有一个通用的,其类型在运行时确定。 泛型提供强类型,但是这仅仅是可能的,如果你知道在编译时的类型。 这是它,因为你知道什么是行动对象可以执行提供安全泛型最强的优势之一。 在运行时,如果你不知道你做什么类型的,即违背了这个目的,你必须深入思考的强大(但有时甚至是危险的)世界。 例如,
List<DateTime> list = new List<DateTime>();
foreach (DateTime item in list)
item.Minute + ": " + item.Hour
因为我知道在编译时的类型,我可以将其存储在一个通用的容器中,我使用它的时候有型的安全性。 我知道这个项目有一个分针和时针财产。
如果您想根据执行操作的对象是什么类型的,那么你使用的GetType()方法。 这是你的窗户进入运行时类型识别和处理。
Result PerformQuery(object unknownObject)
{
switch (object.GetType())
{
case typeof(ThisType): Do This; break;
case typeof(ThatType): Do That; break;
}
}
如果你打算做一些与该对象,那么你要么知道在编译时的方法名称,这意味着你可以使用接口,
IFood hamburger = new Hamburger();
hamburger.BeEaten();
如果你没有或者不想使用你可以使用反射或动态的界面,在这种情况下,我想,如果我知道我要叫什么方法使用动态。
Result PerformQuery(object unknownObject)
{
if (object.GetType() == typeof(Pizza))
{
dynamic pizza = unknownObject;
pizza.BakeInOven() // since I checked and know it is type Pizza it is 'somewhat' safe to do this, unless Pizza class changes the name of BakeInOven method.
}
}
最后,如果你不知道你想在编译时,你可以使用反射来调用方法。
string methodName = CalculateWhatMethodShouldBe();
MethodInfo myMethod = unknownObject.GetType().GetMethods().First(m => m.Name == methodName);
MethodInfo.Invoke(unknownObject);