首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将Class<Derived>转换为Class<Base>?

如何将Class<Derived>转换为Class<Base>?
EN

Stack Overflow用户
提问于 2015-11-19 16:10:25
回答 3查看 53关注 0票数 1

我有一个具有多个派生类的基类:

代码语言:javascript
复制
class Base { }

class Derived1 : Base { }

class Derived2 : Base { }

然后我有一个worker类,它将这个类作为泛型类型:

代码语言:javascript
复制
class WorkerClass<T> where T : Base, new()
{
    WorkerClass() { }

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

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

代码语言:javascript
复制
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-否则,但这似乎是不必要的重复。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-11-19 16:17:14

我可能误解了您的意图,但我认为您可以使用带有约束的泛型来做这样的事情:

代码语言:javascript
复制
void DoStuff<T>() where T : Base, new()
{
  WorkerClass<T> worker_class = new WorkerClass<T>();

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

在那里,您可以简单地调用,例如:

代码语言:javascript
复制
DoStuff<Derived1>();
票数 2
EN

Stack Overflow用户

发布于 2015-11-19 16:14:12

我对您的代码做了几处修改,以使其正常工作。您的WorkerClass<T>也需要从Base类继承,如果要执行的代码而不是Base类中的DoStuff方法,则可能需要重写超类中的DoStuff调用。

代码语言:javascript
复制
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
        }
    }
票数 1
EN

Stack Overflow用户

发布于 2015-11-19 16:18:29

您可以使用协方差,但只有接口和委托才支持它。尝试引入接口IWorkerClass<out T>out关键字将模板类型T标记为协变量。

代码语言:javascript
复制
interface IWorkerClass<out T> 
{
    void DoStuff();
}

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

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

代码语言:javascript
复制
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();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33808931

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档