如何使用未知类型参数在 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;
}
我似乎有两个问题:
- 我无法将方法标记为
abstract
,因为我需要知道实体类型。
- 如果我将方法标记为
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
};
}
我正在尝试定义一个 "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;
}
我似乎有两个问题:
- 我无法将方法标记为
abstract
,因为我需要知道实体类型。 - 如果我将方法标记为
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
};
}