C#generics字符串解析为任何对象

我将对象值存储在字符串中,例如,

string[] values = new string[] { "213.4", "10", "hello", "MyValue"}; 

有没有办法一般初始化适当的对象类型? 比如,像

 double foo1 = AwesomeFunction(values[0]); int foo2 = AwesomeFunction(values[1]); string foo3 = AwesomeFunction(values[2]); MyEnum foo4 = AwesomeFunction(values[3]); 

其中AwesomeFunction是我需要的function。 最终用途是初始化属性,例如,

 MyObject obj = new MyObject(); PropertyInfo info = typeof(MyObject).GetProperty("SomeProperty"); info.SetValue(obj, AwesomeFunction("20.53"), null); 

我需要这样的function的原因是我将所述值存储在数据库中,并希望通过查询读出它们,然后初始化对象的相应属性。 这有可能吗? 整个对象没有存储在数据库中,只是我想要动态读取和设置的几个字段。 我知道我可以静态地完成它,但是这将变得乏味,难以维护,并且正在阅读具有许多不同字段/属性的容易出错的情况。

编辑:如果AwesomeFunction可以使用指定接受字符串的构造函数的自定义类,则AwesomeFunction奖励积分!

EDIT2:在我要使用此类function的特定情况下,可以通过PropertyType了解目标类型。 我认为Enums很容易解析,例如,

 Type destinationType = info.PropertyType; Enum.Parse(destinationType, "MyValue"); 

也许首先要尝试的是:

 object value = Convert.ChangeType(text, info.PropertyType); 

但是,这不支持通过自定义类型的可扩展性; 如果你需要那个 ,怎么样:

 TypeConverter tc = TypeDescriptor.GetConverter(info.PropertyType); object value = tc.ConvertFromString(null, CultureInfo.InvariantCulture, text); info.SetValue(obj, value, null); 

要么:

 info.SetValue(obj, AwesomeFunction("20.53", info.PropertyType), null); 

 public object AwesomeFunction(string text, Type type) { TypeConverter tc = TypeDescriptor.GetConverter(type); return tc.ConvertFromString(null, CultureInfo.InvariantCulture, text); } 
 public T Get(string val) { if (!string.IsNullOrWhiteSpace(val)) return (T) TypeDescriptor.GetConverter(typeof (T)).ConvertFromString(val); else return default(T); } 

这是一个简单的版本:

 object ConvertToAny(string input) { int i; if (int.TryParse(input, out i)) return i; double d; if (double.TryParse(input, out d)) return d; return input; } 

它将识别整数和双精度数,但其他所有内容都以字符串forms返回。 处理枚举的问题在于,无法知道值属于哪个枚举,并且无法判断它是否应该是字符串。 其他问题是它不处理日期/时间或小数(你如何区分它们与双打?)等。

如果您愿意更改代码,请执行以下操作:

 PropertyInfo info = typeof(MyObject).GetProperty("SomeProperty"); info.SetValue(obj, AwesomeFunction("20.53", info.PropertyType), null); 

然后它变得非常容易:

 object ConvertToAny(string input, Type target) { // handle common types if (target == typeof(int)) return int.Parse(input); if (target == typeof(double)) return double.Parse(input); ... // handle enums if (target.BaseType == typeof(Enum)) return Enum.Parse(target, input); // handle anything with a static Parse(string) function var parse = target.GetMethod("Parse", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, null, new[] { typeof(string) }, null); if (parse != null) return parse.Invoke(null, new object[] { input }); // handle types with constructors that take a string var constructor = target.GetConstructor(new[] { typeof(string) }); if (constructor != null) return constructor.Invoke(new object[] { input }); } 

编辑:添加了缺少的括号

我知道这不能回答你的问题,但是你看过Dapper micro ORM吗?
这是简单的(与LINQ to SQL相比,或者,出于这个原因,entity framework)并且做你想要的。

考虑一下:

 public class Dog { public int? Age { get; set; } public Guid Id { get; set; } public string Name { get; set; } public float? Weight { get; set; } } var guid = Guid.NewGuid(); var dog = connection.Query("select * from Dogs where Id = @Id", new { Id = 42 } ).First(); 

Dapper本身打包在一个文件中 ,据报道, StackOverflow团队使用它 (除了Linq到SQL)。