如何使用未知类型参数在 C# 中的派生 class 上正确定义和调用方法

How to properly define and call a method on a derived class in C# with an unknown type parameter

我正在尝试定义一个 "Transformation" class,它将负责返回一个基于复杂类型的简化数组对象。 class 将通过接受复杂类型的 "transform" 方法完成此操作。这是基于分形 (http://fractal.thephpleague.com/transformers/),但我正在尝试在 C# 中实现类似的东西。

到目前为止,我已经定义了一个抽象基础TransformerAbstract class,其中包含一些对每个派生转换器通用的属性和方法class:

public abstract class TransformerAbstract
{
    public abstract object transform(object entity);
}

我正在为如何实现 transform 方法而苦恼,因为我需要知道复杂类型是什么,这样我才能创建转换,每个派生转换都会有所不同 class (例如:CycleTransformer等)

 public class CycleTransformer : TransformerAbstract
 {
    public override object transform(object entity)
    {
        throw new NotImplementedException();
    }
}

我的应用程序中还有其他几个地方我希望能够转换数据 - 例如,采用以下代码段:

    protected object[] fireTransformer(TransformerAbstract transformer, object data)
    {
        var includedData = new object();

        var transformedData = transformer.transform(data);

        if (transformerHasIncludes(transformer))
        {
            includedData = fireIncludedTransformers(transformer, data);
            //serialize & merge includes
        }

        object[] returnData = new object[1];
        returnData[0] = transformedData;
        returnData[1] = includedData;

        return returnData;
    }

我似乎有两个问题:

  1. 我无法将方法标记为 abstract,因为我需要知道实体类型。
  2. 如果我将方法标记为 virtual 那么代码总是调用基础 class 而不是派生的,即使我可以在 运行 时间通过调试看到class 的正确实例已生成。

我很早就尝试使用泛型(例如 TransformerAbstract<T> : ITransformer<T>),但这迫使我对任何使用 TransformerAbstract 的 class 提供类型约束,我认为这限制过度。

我不确定这是否适用于您的情况。您可以尝试 virtual 和 override 关键字。

public abstract class TransformerAbstract
{
    public virtual object transform(object entity);
}

public class CycleTransformer : TransformerAbstract
 {
    public override object transform(object entity)
    {
        throw new NotImplementedException();
    }
}

看看下面的代码。

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

namespace Test
{
    class A
    {
        public virtual void show()
        {
            Console.WriteLine("Base Class!");
            Console.ReadLine();
        }
    }

    class B : A
    {
        public override void show()
        {
            Console.WriteLine("Derived Class!");
            Console.ReadLine();
        }
    }

    class Polymorphism
    {
        public static void Main()
        {          
            A a2 = new B();
            a2.show(); // calls derived class.
        }
    }
}

这会满足您的需求吗?

    public class CycleTransformer : TransformerAbstract
    {
        public override object Transform(object entity)
        {
            if (entity is CycleData)
            {
                // Do transform
            }
            else if (entity is FireData)
            {
                // Do transform
            }
            else
            {
                throw new NotImplementedException();
            }
        }
    }

我可能会停止使用对象,而是使用接口。

interface ITransformResult<T>
{

}

interface ITransformable<T>
{

}

interface ITransformInclude<T>
{

}

interface ITransformer<T>
{
    ITransformResult<T> Transform(ITransformable<T> data);
    bool HasIncludes { get; }

    IEnumerable<ITransformInclude<T>> FireIncludes(ITransformable<T> data);
}

class TransformedData<T>
{
    public ITransformResult<T> Result { get; set; }
    public IEnumerable<ITransformInclude<T>> Includes { get; set; }
}

现在你有了一个强类型结构,你的函数将很简单:

protected TransformedData<T> fireTransformer<T>(ITransformer<T> transformer,
                                                ITransformable<T> data)
{
    return new TransformedData<T>
    {
        Result = transformer.Transform(data),
        Includes = transformer.HasIncludes 
                   ? transformer.FireIncludes(data) 
                   : null
    };
}