2015-11-19 98 views
1

我有多个派生类基类:如何将类<Derived>转换为<Base>类?

class Base { } 

class Derived1 : Base { } 

class Derived2 : Base { } 

然后我有职工类,借此类作为一个通用的类型:

class WorkerClass<T> where T : Base, new() 
{ 
    WorkerClass() { } 

    void DoStuff() 
    { 
     T container = new T(); 
     // do stuff 
    } 
} 

问题是,当我实例WorkerClass,我只有类型作为变量。我想这样做:

void DoStuff(Type type) 
{ 
    WorkerClass<Base> worker_class = null; 

    if(type == typeof(Derived1)) 
    { 
     worker_class = new WorkerClass<Derived1>(); // compiler error 
    } 
    else if(type == typeof(Derived2)) 
    { 
     worker_class = new WorkerClass<Derived2>(); // compiler error 
    } 

    // lots of common code with worker_class 
    worker_class.DoStuff(); 
} 

但是,编译器会抱怨隐式铸造WorkerClass<Derived>WorkerClass<Base>。明确的转换也会给出一个错误。编译器建议定义public static implicit operator WorkerClass<T>(WorkerClass<Derived>),但我不确定代码的外观。我明显可以把所有的逻辑放在if-else中,但似乎是不必要的重复。

+1

代替'DoStuff(类型类型)'使用通用的方法。 'DoStuff ()其中T2:Base,new()' –

回答

2

我可能会误解你的意图,但我认为你可以做这样的事情使用泛型与约束:

void DoStuff<T>() where T : Base, new() 
{ 
    WorkerClass<T> worker_class = new WorkerClass<T>(); 

    // lots of common code with worker_class 
    worker_class.DoStuff(); 
} 

从那里,你会简单地调用,例如:

DoStuff<Derived1>(); 
+1

接受为最简单的解决方案。谢谢。 –

1

我对你的代码做了几处更正,以使其正常工作。您的WorkerClass<T>需要继承Base课程,如果您要执行该代码而不是Base类中的DoStuff方法,则可能需要覆盖超类中的DoStuff调用。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace ConsoleApplication6 
{ 
    public class Base 
    { 
     public virtual void DoStuff(){} 
    } 

    public class Derived1 : Base 
    { 
     public virtual void DoStuff(){} 
    } 

    public class Derived2 : Base 
    { 
     public virtual void DoStuff(){} 
    } 

    public class WorkerClass<T> : Base where T : Base,new() 
    { 
     public WorkerClass() { } 

     public override void DoStuff() 
     { 
      T container = new T(); 
      // do stuff 
     } 
    } 
0

您可以使用covariance,但仅支持接口和代理。尝试介绍接口IWorkerClass<out T>out关键字将模板类型T标记为协变。

interface IWorkerClass<out T> 
{ 
    void DoStuff(); 
} 

class WorkerClass<T> : IWorkerClass<T> where T : Base, new() 
{ 
    public void DoStuff() { } 
} 

然后在您的代码示例使用的接口而不是类的:

void DoStuff(Type type) 
{ 
    IWorkerClass<Base> worker_class = null; 

    if(type == typeof(Derived1)) 
    { 
     worker_class = new WorkerClass<Derived1>(); // NO compiler error 
    } 
    else if(type == typeof(Derived2)) 
    { 
     worker_class = new WorkerClass<Derived2>(); // NO compiler error 
    } 

    // lots of common code with worker_class 
    worker_class.DoStuff(); 
} 
相关问题