使用此关键字时使用C#泛型类型
本文关键字:泛型类型 关键字 | 更新日期: 2023-09-27 18:27:38
我放在一起的对象是为了允许一个对象将自己暴露为可以由另一个相同类型的对象转换的东西。按照合并的思路思考,但操作不是通用的/直接的,因此您可以使用反射来简单地获取所有属性并执行一些预定的操作集。因此,我决定尝试将其实现为将自己公开为Transformable的对象,并为其附加一个知道如何执行转换的对象(可以互换)。到目前为止,我拥有的可编译代码是:
public interface ITransformer<TType> where TType : class
{
void Transform(TType source, TType destination);
}
public interface ITransformable<TType> where TType : class
{
bool Locked { get; set; }
ITransformer<TType> Transformer { get; set; }
void TransformFrom(TType source);
}
public class MyTransformer : ITransformer<MyTransformable>
{
public void Transform(MyTransformable source, MyTransformable destination)
{
// Perform some logic for the transform
}
}
public class MyTransformable : ITransformable<MyTransformable>
{
public bool Locked { get; set; }
public ITransformer<MyTransformable> Transformer { get; set; }
public string Value1 { get; set; }
public uint Value2 { get; set; }
public bool Value3 { get; set; }
public void TransformFrom(MyTransformable source)
{
Transformer.Transform(source, this);
}
}
正如您所看到的,类型MyTransformable包含一些数据(Value1-Value3)以及Locked状态,Transformer对象将知道如何对此项目执行转换(泛型确保只允许能够对MyTransformer类型执行操作的转换器)。
我的问题是,我不希望所有Transformable类型的新对象都必须重复调用
public void TransformFrom(MyTransformable source)
{
Transformer.Transform(source, this);
}
所以我希望我可以将MyTransformable对象添加到
public abstract class Transformable<TType> : ITransformable<TType> where TType : class
{
public bool Locked { get; set; }
public ITransformer<TType> Transformer { get; set; }
public void TransformFrom(TType source)
{
Transformer.Transform(source, this); // ERROR! this is type Transformable<TType> not TType
}
}
public class MyTransformable : Transformable<MyTransformable>
{
}
当然,由于我强调的错误,这不会编译。我觉得我在某些方面没有抓住要点。有人能为我指出正确的方向吗?
您需要做的是为派生类型添加一个钩子,以公开最终的、真实的TType
实现(或简称this
)。这最好通过抽象属性来完成。
public abstract class Transformable<TType> : ITransformable<TType>
{
public bool Locked { get; set; }
public ITransformer<TType> Transformer { get; set; }
protected abstract TType Value { get; }
public void TransformFrom(TType source)
{
Transformer.Transform(source, Value);
}
}
public class MyOtherTransformable : Transformable<MyTransformable>
{
protected override MyTransformable Value
{
get { return this; }
}
}
如果您使用的是.NET 4,则可以使用到dynamic
:的强制转换
public void TransformFrom(TType source)
{
Transformer.Transform(source, (dynamic)this);
}
这允许CLR在运行时根据执行时对象的实际类型(封闭泛型)进行参数类型匹配,从而防止编译时出错。在运行时,CLR可以很容易地判断出source
和this
是同一类型,并将执行调用。
好处是它解决了你的问题。缺点是dynamic
的使用是一个固有的反射过程,它首先较慢,其次可能隐藏会导致运行时异常的错误。
这将导致比您可能满意的更多的选角,甚至可能无法实现您想要做的事情,但这会编译:
public interface ITransformable { }
public interface ITransformer<TType>
where TType: ITransformable
{
void Transform(ITransformable source, ITransformable destination);
}
public interface ITransformable<TType> : ITransformable
where TType: ITransformable
{
bool Locked { get; set; }
ITransformer<TType> Transformer { get; set; }
void TransformFrom(TType source);
}
public class MyTransformer : ITransformer<MyTransformable>
{
public void Transform(ITransformable source, ITransformable destination)
{
if (source.GetType() != destination.GetType())
throw new InvalidOperationException();
// Perform some logic for the transform
}
}
public abstract class Transformable<TType> : ITransformable<TType> where TType: ITransformable
{
public bool Locked { get; set; }
public ITransformer<TType> Transformer { get; set; }
public void TransformFrom(TType source)
{
Transformer.Transform(source, this);
}
}
public class MyTransformable : Transformable<MyTransformable>
{
}