字符串的通用generics类型转换

我的任务是编写一个StringToType()方法,将字符串转换为指定的类型T.

  1. 对于基本类型,我使用Convert.ChangeType()方法
  2. 对于枚举类型 – Enum.TryParse()
  3. 对于所有其他自定义类型,我创建了一个接口“IConvertibleFromString”,其中包含一个方法“FromString()”,将字符串转换为指定的类型。 任何需要从字符串转换的类都必须实现此接口。

但我不喜欢我实现方法StringToType()的方式。 我想使用少于reflection并尽可能确保性能。

请告知如何最好地实施/更改它。

class Program { static bool StringToType(string str, ref T value) { Type typeT = typeof(T); bool isSuccess = false; if (typeT.GetInterface("IConvertibleFromString") != null) { return (bool)typeT.GetMethod("FromString").Invoke(value, new object[] { str }); } else if (typeT.IsEnum) { MethodInfo methodTryParse = typeT.GetMethod("TryParse").MakeGenericMethod(typeT); return (bool)methodTryParse.Invoke(null, new object[] { str, value }); } else if (typeT.IsPrimitive) { value = (T)Convert.ChangeType(str, typeT); return true; } return isSuccess; } static void Main(string[] args) { string intStr = "23"; int val1 = 0; bool res = StringToType(intStr, ref val1); Class1 c1; res = StringToType(intStr, ref c1); Console.ReadKey(); } } interface IConvertibleFromString { bool FromString(string str); } class MySomeClass : IConvertibleFromString { int someVal; public bool FromString(string str) { return int.TryParse(str, out someVal); } } 

这似乎对我来说是最好的。 与各种消费者共同投入了一百万次。 这是人们评论的结合,还有一些额外的评论。

  static Boolean TryParseString( String stringValue, ref T value) { Type typeT = typeof(T); if (typeT.IsPrimitive) { value = (T)Convert.ChangeType(stringValue, typeT); return true; } else if (typeT.IsEnum) { value = (T)System.Enum.Parse(typeT, stringValue); // Yeah, we're making an assumption return true; } else { var convertible = value as IConvertible; if (convertible != null) { return convertible.FromString(stringValue); } } return false; } 

对于案例#1,它已经是最佳的。

对于情况#2,您可以使用Enum.Parse并捕获ArgumentException并返回false。

对于情况#3方法, FromString是一个静态工厂方法,因此不包含在接口IConvertibleFromString (所以接口只是一个类型标记并且不包含任何方法)或者它是一个实例方法,它会改变this._value或者其他东西,它是不清楚。 如果是后者,那么只需将value IConvertibleFromStringIConvertibleFromString并调用FromString ,就不需要reflection。 如果它是静态工厂方法,那么你必须使用reflection。

事物的当前结构不允许它是真正的StringToType,因为你不能调用FromString,因为你有一个“已经活动”的实例。 调用FromString时,会创建并返回另一个实例 – 这意味着每次需要创建2个实例实例以实现所需的实例。

如果你想要它完美地工作,这是我的建议:

  1. 创建一个新类 – “StringActivator”(灵感来自Reflection的Activator)

  2. 创建一个Type方法 – StringActivator.CreateInstance(string …)

  3. 激活字符串是一个由逗号分隔/ xml字符串组成的字符串,其中每个项都是构造函数参数。

  4. 在里面,遍历类型(T)构造函数并查找具有所请求参数数量的所有构造函数(在激活字符串中发送)。

  5. 现在,一旦你拥有了所有构造函数,尝试将你在激活字符串中发送的每个参数值转换为构造函数使用Recursion所期望的类型(调用StringActivator.CreateInstane,其中T是构造函数所期望的类型)。

为此,如果T是Primitive或ENum(递归的停止条件),则需要检查CreateInstance的开头,然后使用(T)转换。

  1. 当您转换所有逗号分隔的参数时,请使用Reflection.Emit为您发送的特定数量的参数创建编译调用。

  2. 将发出的函数委托映射到Type sent(),并在下次尝试从具有相同参数数量的字符串转换为T时调用它…

希望能帮助到你。