2012-10-16 130 views
2

抽象类,我有两个类:获得通过字符串名称

class Car<T> 
{ 
    public string color { get; set; } 
    public virtual T features { get; set; } 
    public virtual void TestDrive(); 
} 
class Toyota : Car<ToyotaFeatures> 
{ 
    public override ToyotaFeatures features { get; set; } 
    public override void TestDrive() 
    { 
     //Logic here... 
    } 
} 

现在我有一个完整的串类的名称:“MySol.MyProj.Toyota”
我想通过我的字符串名称实例化一个类和然后运行TestDrive()。
问题是,当我尝试运行Activator.CreateInstance(null, "MySol.MyProj.Toyota");
我不能将其强制转换到基类并运行testDrive,因为它期望ToyotaFeatures类被传递给它。但我只想运行TestDrive()只有一个字符串类名称。

而我不想将它转换为特定类型。只适用于基本类型,因此它可以根据提供的字符串决定运行哪个TestDrive()。

+1

要实例强制转换为基类为什么呢?你不想在你的实例上运行TestDrive方法吗?例如,myInstance.TestDrive() –

回答

3

为此,界面非常好。

interface ITestDrivable 
{ 
    void TestDrive(); 
} 

你的抽象类实现的接口:

class Car<T> : ITestDrivable 
{ 
    public string Color { get; set; } 
    public virtual T Features { get; set; } 
    public abstract void TestDrive() { } 
} 

和铸造,这非常容易:

ITestDrivable car = (ITestDrivable)Activator.CreateInstance(null, "MySol.MyProj.Toyota"); 
car.TestDrive(); 
+0

看起来很棒。你也可以解释一下,我该如何将泛型dataRow传递给构造函数,以便我可以填充颜色和其他属性? – user194076

+0

我可以在派生类中做这个吗?事情是,我有一个泛型方法,名为:convertToObject (DataRow dr),它返回myType的对象,但我不知道如何在构造函数中使用它。我正在考虑这样的事情:this = ConvertToObject (dr),但这是不允许的。 – user194076

+0

或者也许我可以在TestDrive(DataRow dr)方法中以某种方式执行此操作。 – user194076

3
Type type = Type.GetType("MySol.MyProj.Toyota"); 

var obj = Activator.CreateInstance(type); 
type.GetMethod("TestDrive").Invoke(obj, null); 
+0

反射速度很慢,应该在**没有其他方式**时使用。 – AgentFire

+0

这样可以将参数传递给构造函数吗?我必须投到基类 – user194076

+1

@ user194076你可以传递参数在一个对象数组('Activator.CreateInstance(type,new object [] {param1,param2}')。 –

0

将有任何意义:

abstract class CarFeatures { } 

class ToyotaFeatures : CarFeatures { } 

abstract class Car 
{ 
    public string color { get; set; } 
    public virtual void TestDrive() { } 
} 

abstract class Car<T> : Car where T : CarFeatures 
{ 
    public virtual T features { get; set; } 

    public Car(T _features) 
    { 
     features = _features; 
    } 
} 

class Toyota : Car<ToyotaFeatures> 
{ 
    public override ToyotaFeatures features { get; set; } 

    public Toyota(ToyotaFeatures _features) : base(_features) { } 

    public override void TestDrive() 
    { 
     //Logic here... 
    } 
} 

不止一次,我从非泛型类派生了我的泛型类,以便将所有通用方法和字段与泛型无关,从而使我可以轻松访问它们。

ToyotaFeatures features = new ToyotaFeatures(); 
Car car = (Car)Activator.CreateInstance(typeof(Toyota), new object[] { features }); 
car.TestDrive(); 

但是,如果有人有更好的解决方案,我也会被采访。

编辑:如上所述,界面很酷,但我的经验法则是“不要创建一个接口,如果你只用于一个类”。但它的工作。

重新编辑:问题是实例化泛型对象与params集合。

+0

我不能投向丰田,因为我只有一个班级的字符串名称,也可以是本田。 – user194076

+0

如果您只想调用TestDrive,您为什么要投向丰田?是否有特殊的方法在丰田,你想访问?编辑:啊!我想我看到你要去哪里,这是你正在创建一个新的对象,你很难在初始化时填充它的字段 – LightStriker

+0

你去了吗? .CreateInstance允许你传递一个构造函数所需的参数,如果你的基类定义了一个需要CarFeatures的构造函数,你可以设置它们来创建你的对象。你的对象应该正确设置来调用它的方法。 – LightStriker

0

您应该在您的类中实现接口IConvertible,然后使用方法Convert.ChangeType(..)。代码示例可能是:

// hords the created object 
    object createdByActivator = ....; 
    Car objectAsCar = Convert.ChangeType(createdByActivator, Type.GetType("MySol.MyProj.Toyota" 

+0

'Car objectAsCar'的东西在你的代码中就是他的问题。他不能只写'Car',因为它是一个泛型类,它实际上是Car <>'。 – AgentFire

相关问题