C# 类,该类使用注册的lambda将一种类型转换为另一种类型

C# 类,该类使用注册的lambda将一种类型转换为另一种类型,c#,lambda,C#,Lambda,我想制作一个类TypeConverter。这门课应该做到: 1) 它应该允许注册指定类型的转换(我的exmaple中的int到string) 在我不工作的实现中,我使用了:字典映射以存储我的转换器。注册函数如下所示: public void Register<TIn, TOut> (Converter<TIn, TOut> converter) { map.Add (typeof (TIn), () => converter); }

我想制作一个类
TypeConverter
。这门课应该做到:

1) 它应该允许注册指定类型的转换(我的exmaple中的int到string)

在我不工作的实现中,我使用了:
字典映射以存储我的转换器。注册函数如下所示:

   public void Register<TIn, TOut> (Converter<TIn, TOut> converter)
   {
        map.Add (typeof (TIn), () => converter);
   }
publicstatict-ConvertTo(对象值)
{
尝试
{
return(T)Convert.ChangeType(value,typeof(T),CultureInfo.InvariantCulture);
}
捕获(例外情况除外)
{
return(T)(typeof(T).IsValueType?Activator.CreateInstance(typeof(T)):null);
}
}
你可以用这个方法。下面是如何使用它的示例:

   string test = "5";
   decimal d = ConvertTo<decimal>(test);
static void Main(string[] args)
{
    var converter = new TypeConverter();

    converter.Register<int, string>(value => (value + 1).ToString());

    string x = converter.Convert<int, string>(5);

    object boxedInt = 5;

    string y = (string)converter.Convert(boxedInt);
}
string test=“5”;
十进制d=转换到(测试);

假设您有理由构建自己的自定义类型转换器,下面是一种方法:

用法:

TypeConverter converter = new TypeConverter();
converter.Register<int, string>((a) => a == 3 ? "three!" : a.ToString());
converter.Register<int, int>((a) => 3);

string resultAsString = converter.Convert<string>(3); // returns "three!"
int resultAsInt = converter.Convert<int>(4); // returns 3
TypeConverter converter=新的TypeConverter();
寄存器((a)=>a==3?“三!”:a.ToString();
转换器寄存器((a)=>3);
string resultAsString=converter.Convert(3);//返回“三!”
int resultAsInt=converter.Convert(4);//返回3
类型转换,调用委托,并将结果强制转换为目标类型

public class TypeConverter
{
    private Dictionary<KeyValuePair<Type, Type>, Delegate> _map = new Dictionary<KeyValuePair<Type, Type>, Delegate>();

    public void Register<TIn, TOut>(Converter<TIn, TOut> converter)
    {
        _map.Add(new KeyValuePair<Type,Type>(typeof(TIn),typeof(TOut)), converter);
    }

    public T Convert<T>(object o)
    {
        Type inputType = o.GetType();
        Delegate converter = null;
        KeyValuePair<Type, Type> mapKey = new KeyValuePair<Type, Type>(inputType, typeof(T));
        if (_map.TryGetValue(mapKey, out converter))
            return (T)converter.Method.Invoke(null, new object[] { o });

        throw new NotSupportedException(String.Format("No converter available for {0} to {1}", o.GetType().Name, typeof(T).Name));
    }
}
公共类类型转换器
{
私有字典_map=新字典();
公共无效寄存器(转换器)
{
_添加(新的键值对(typeof(TIn)、typeof(TOut))、转换器;
}
公共T转换(对象o)
{
类型inputType=o.GetType();
委托转换器=空;
KeyValuePair mapKey=新的KeyValuePair(输入类型,类型(T));
if(_map.TryGetValue(映射键,输出转换器))
return(T)converter.Method.Invoke(null,新对象[]{o});
抛出新的NotSupportedException(String.Format(“没有可用于{0}到{1}的转换器”,o.GetType().Name,typeof(T.Name));
}
}

在如何以非泛型的方式使用泛型类方面,我也有过类似的学习经历,直到我简单地点击一下:使用接口,我才明白这一点。因此,如果您想以非泛型的方式使用泛型转换器,请定义一个非泛型接口并实现它。除非您执行检查以处理该问题,否则您将失去任何类型的安全

因此,在您的情况下,定义一个非泛型接口

private interface IConvertor {
    object Convert(object obj);
}
在封装lambda的泛型转换器类中实现它

private class Convertor<TIn, TOut> : IConvertor {
    public Convertor(Func<TIn, TOut> conversion) {
        _conversion = conversion;
    }
    private readonly Func<TIn, TOut> _conversion;
    object IConvertor.Convert(object obj) {
        if (obj is TIn) {
            return _conversion((TIn)obj);
        }
        throw new NotSupportedException();
    }
}

简单易懂。当然,您已经通过存储
Func
完成了类似的操作,但不幸的是,这不起作用,因为它不是一个接口,而且从
Func
Func
的转换也不起作用。

这里有一个简单的解决方案:

class TypeConverter
{
    private readonly IDictionary<Type, Delegate> map = new Dictionary<Type, Delegate>();

    public void Register<TInput, TOutput>(Converter<TInput, TOutput> converter)
    {
        if (converter == null)
            throw new ArgumentNullException("converter");

        this.map.Add(typeof(TInput), converter);
    }

    public TOutput Convert<TInput, TOutput>(TInput value)
    {
        return ((Converter<TInput, TOutput>)this.map[typeof(TInput)])(value);
    }

    public object Convert(object value)
    {
        if (value == null)
            throw new ArgumentNullException("value");

        return this.map[value.GetType()].DynamicInvoke(value);
    }
}
类类型转换器
{
私有只读IDictionary map=new Dictionary();
公共无效寄存器(转换器)
{
if(converter==null)
抛出新的ArgumentNullException(“转换器”);
这个.map.Add(typeof(TInput),转换器);
}
公共TOutput转换(TInput值)
{
返回((转换器)this.map[typeof(TInput)](值);
}
公共对象转换(对象值)
{
如果(值==null)
抛出新的ArgumentNullException(“值”);
返回此.map[value.GetType()].DynamicInvoke(value);
}
}
下面是如何使用它:

   string test = "5";
   decimal d = ConvertTo<decimal>(test);
static void Main(string[] args)
{
    var converter = new TypeConverter();

    converter.Register<int, string>(value => (value + 1).ToString());

    string x = converter.Convert<int, string>(5);

    object boxedInt = 5;

    string y = (string)converter.Convert(boxedInt);
}
static void Main(字符串[]args)
{
var converter=新类型转换器();
Register(value=>(value+1.ToString());
字符串x=转换器。转换(5);
物体力=5;
字符串y=(字符串)converter.Convert(boxedInt);
}

请注意,此解决方案使用的是非常缓慢的,因此,如果您正在寻找性能更高的解决方案,则应使用前面提到的泛型类,该类包装委托并实现暴露弱类型转换方法的接口。

谢谢,我昨天提出了完全相同的解决方案。
public class TypeConvertor {
    private readonly Dictionary<Type, IConvertor> _convertors =
        new Dictionary<Type, IConvertor>();

    public void Register<TIn, TOut>(Func<TIn, TOut> conversion) {
        _convertors.Add(typeof(TIn), new Convertor<TIn, TOut>(conversion));
    }

    public object Convert(object obj) {
        if (obj == null)
            throw new ArgumentNullException("obj");
        return _convertors[obj.GetType()].Convert(obj);
    }
}
class TypeConverter
{
    private readonly IDictionary<Type, Delegate> map = new Dictionary<Type, Delegate>();

    public void Register<TInput, TOutput>(Converter<TInput, TOutput> converter)
    {
        if (converter == null)
            throw new ArgumentNullException("converter");

        this.map.Add(typeof(TInput), converter);
    }

    public TOutput Convert<TInput, TOutput>(TInput value)
    {
        return ((Converter<TInput, TOutput>)this.map[typeof(TInput)])(value);
    }

    public object Convert(object value)
    {
        if (value == null)
            throw new ArgumentNullException("value");

        return this.map[value.GetType()].DynamicInvoke(value);
    }
}
static void Main(string[] args)
{
    var converter = new TypeConverter();

    converter.Register<int, string>(value => (value + 1).ToString());

    string x = converter.Convert<int, string>(5);

    object boxedInt = 5;

    string y = (string)converter.Convert(boxedInt);
}