C# 字符串的通用泛型类型转换
我的任务是编写一个方法StringToType(),将字符串转换为指定的类型TC# 字符串的通用泛型类型转换,c#,generics,type-conversion,C#,Generics,Type Conversion,我的任务是编写一个方法StringToType(),将字符串转换为指定的类型T 对于基元类型,我使用Convert.ChangeType()方法 对于枚举类型-enum.TryParse() 对于所有其他自定义类型,我创建了一个接口“IConvertibleFromString”,其中包含一个方法“FromString()”,用于将字符串转换为指定类型。任何需要从字符串转换的类都必须实现此接口 但是我不喜欢我实现方法StringToType()的方式。我希望使用较少的反射,并尽可能确保性能 请告
class Program
{
static bool StringToType<T>(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<int>(intStr, ref val1);
Class1 c1;
res = StringToType<Class1>(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);
}
}
类程序
{
静态bool StringToType(字符串str,ref T值)
{
类型T=类型(T);
bool isSuccess=错误;
if(typeT.GetInterface(“IConvertibleFromString”)!=null)
{
return(bool)typeT.GetMethod(“FromString”).Invoke(值,新对象[]{str});
}
else if(输入IsEnum)
{
MethodInfo methodTryParse=typeT.GetMethod(“TryParse”).MakeGenericMethod(typeT);
return(bool)methodrParse.Invoke(null,新对象[]{str,value});
}
else if(类型为IsPrimitive)
{
value=(T)Convert.ChangeType(str,typeT);
返回true;
}
返回成功;
}
静态void Main(字符串[]参数)
{
字符串intStr=“23”;
int val1=0;
bool res=StringToType(intStr,ref val1);
1类c1;
res=StringToType(intStr,参考c1);
Console.ReadKey();
}
}
接口IConvertibleFromString
{
bool-FromString(stringstr);
}
类MySomeClass:IConvertibleFromString
{
int-someVal;
公共bool FromString(string str)
{
返回int.TryParse(str,out someVal);
}
}
这对我来说似乎是最好的。对不同的消费者进行了一百万次迭代。这是一个结合了人们的意见,有一点额外的
static Boolean TryParseString<T>(
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;
}
static Boolean TryParseString(
字符串字符串值,参考T值)
{
类型T=类型(T);
如果(类型为IsPrimitive)
{
value=(T)Convert.ChangeType(stringValue,typeT);
返回true;
}
else if(输入IsEnum)
{
value=(T)System.Enum.Parse(typeT,stringValue);//是的,我们正在做一个假设
返回true;
}
其他的
{
var可转换=作为IConvertible的值;
如果(可转换!=null)
{
返回可转换的.FromString(stringValue);
}
}
返回false;
}
对于案例1,它已经是最优的
对于案例2,您可以使用Enum.Parse
并捕获ArgumentException
并返回false
例如#3 method
FromString
要么是一个静态工厂方法,因此不包含在接口IConvertibleFromString
中(因此该接口只是一个类型标记,不包含任何方法),要么是一个实例方法,它变异了。_value
或其他什么,它不清楚。如果是后者,则只需将值
强制转换为IConvertibleFromString
并调用FromString
,无需反射。如果是静态工厂方法,则必须使用反射。当前的结构不允许它是真正的StringToType,因为在拥有“已激活”实例之前,不能调用FromString。调用FromString时,将创建并返回另一个实例-这意味着您每次需要创建2个实例来实现所需的功能
如果你想让它完美运行,我的建议是:
希望有帮助。一个简单的优化方法是以最便宜的顺序检查布尔条件(假设GetInterface()的效率最低),而不是执行
if(typeT.GetInterface(“IConvertibleFromString”)!=null){return(bool)typeT.GetMethod(“FromString”).Invoke(value,new object[]{str};}
您可以执行var iface=value作为IConvertibleFromString;如果(iface!=null)返回iface.FromString(str)代码>。那会帮你省下反思的惩罚嗯<代码>IConvertible.FromString()
?你从哪儿弄来的?