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