簡體   English   中英

如何在C#中使用未知類型參數正確定義和調用派生類上的方法

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

我正在嘗試定義一個“ Transformation”類,該類將負責基於復雜類型返回簡化的數組對象。 該類將通過接受復雜類型的“轉換”方法來完成此任務。 這基於Fractal( http://fractal.thephpleague.com/transformers/ ),但是我試圖在C#中實現類似的功能。

到目前為止,我已經定義了一個抽象的TransformerAbstract基類,其中包含一些派生的轉換器類共有的屬性和方法:

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

我正在努力實現transform方法,因為我需要知道復雜的類型是什么,以便我可以創建轉換,這對於每個派生的轉換類都是不同的(例如: 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方法,則即使在運行時通過調試可以看到生成了正確的類實例,代碼也始終調用基類而不是派生類。

我很早就嘗試使用泛型(例如TransformerAbstract<T> : ITransformer<T> ),但是這迫使我對使用TransformerAbstract的任何類提供類型約束,我認為這種約束過於嚴格。

我可能會停止使用對象,而是使用接口。

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
    };
}

我不確定這是否適合您的情況。 您可以嘗試使用虛擬關鍵字和替代關鍵字。

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();
            }
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM