我目前有一个映射设置,可以从一个基类转换为另一个基类。我正在将客户类映射到第三方控件。值是相似的,但有足够的差异,我不能重复使用第三方控件。
_converters = new Dictionary<Type, Func<AnnotationBase, AnnotationMark>>();
_converters.Add( typeof( HighlightAnnotation ), ToHighlighterAnnotationMark );
_converters.Add( typeof( RectangleAnnotation ), ToRedactionAnnotationMark );
_converters.Add( typeof( StampAnnotation ), ToTextStampAnnotationMark );
这可以找到,但我必须在某些地方做额外的施法。例如:
private AnnotationMark ToTextStampAnnotationMark( AnnotationBase tool )
{
TextStampAnnotationMark mark = new TextStampAnnotationMark();
mark.Location = new MarkLocation { X = (int)tool.Location.X, Y = (int)tool.Location.Y };
mark.Size = new MarkSize { Width = (int)tool.Size.Width, Height = (int)tool.Size.Height };
mark.Text = ((StampAnnotation)tool).Text;
return mark;
}
在这个例子中,我必须假设AnnotationBase
是StampAnnotation
我知道恰好是正确的,因为这是在mapper中注册的类型。但是,我很乐意将此方法的签名更改为private TextStampAnnotationMark ToTestStampAnnotationMark( StampAnnotaion )
。
无论如何都要进行功能映射或表现如下吗?
Func<TTool,TMark>()
where TTool : AnnotationBase
where TMark : AnnotationMark
答案 0 :(得分:0)
这并不能完全避免使用任何演员阵容,但它会集中他们并使他们“安全”:
static class ConvertTest
{
static IDictionary<Type, IDictionary<Type, Func<AnnotationBase, AnnotationMark>>> _conversions =
new Dictionary<Type, IDictionary<Type, Func<AnnotationBase, AnnotationMark>>>();
public static TTo Convert<TFrom, TTo>(this TFrom source)
where TFrom : AnnotationBase
where TTo : AnnotationMark
{
var conversion = _conversions[typeof(TFrom)][typeof(TTo)];
return (TTo)conversion(source);
}
public static void RegisterConversion<TFrom, TTo>(Func<TFrom, TTo> conversion)
where TFrom : AnnotationBase
where TTo : AnnotationMark
{
IDictionary<Type, Func<AnnotationBase, AnnotationMark>> toDictionary;
if (!_conversions.TryGetValue(typeof(TFrom), out toDictionary))
{
toDictionary = new Dictionary<Type, Func<AnnotationBase, AnnotationMark>>();
_conversions.Add(typeof(TFrom), toDictionary);
}
toDictionary[typeof(TTo)] = (Func<AnnotationBase, AnnotationMark>)conversion;
}
}
顺便说一下,我没有测试过这段代码(但是编译了:)。
答案 1 :(得分:0)
有点愚蠢,我没有想到它是正确的方式。简单的解决方案是在注册之前投射对象。
converters.Add( typeof( StampAnnotation ),
tool => ToTextStampAnnotationMark( (StampAnnotation)tool );