C# 泛型方法返回类型作为类型参数
我有一个扩展方法,可以将字符串值转换为各种类型,如下所示:C# 泛型方法返回类型作为类型参数,c#,.net,generics,C#,.net,Generics,我有一个扩展方法,可以将字符串值转换为各种类型,如下所示: public static T ToType<T> (this string value, T property) { object parsedValue = default(T); Type type = property.GetType(); try { parsedValue = Convert.ChangeType(v
public static T ToType<T> (this string value, T property)
{
object parsedValue = default(T);
Type type = property.GetType();
try
{
parsedValue = Convert.ChangeType(value, type);
}
catch (ArgumentException e)
{
parsedValue = null;
}
return (T)parsedValue;
}
public static T ToType<T> (this string value, Type type) { ... }
仅为获取属性的类型而指定属性似乎是多余的。我宁愿使用这样的签名:
public static T ToType<T> (this string value, T property)
{
object parsedValue = default(T);
Type type = property.GetType();
try
{
parsedValue = Convert.ChangeType(value, type);
}
catch (ArgumentException e)
{
parsedValue = null;
}
return (T)parsedValue;
}
public static T ToType<T> (this string value, Type type) { ... }
然而,当我尝试以这种方式调用时,编辑器抱怨无法从用法推断扩展方法的返回类型。我可以将T链接到类型参数吗
我错过了什么
谢谢这就是你要找的吗?我已经为演员阵容无效的情况添加了一个额外的捕获
Decimal i = stringName.ToType<Decimal>();
public static T ToType<T>(this string value)
{
object parsedValue = default(T);
try
{
parsedValue = Convert.ChangeType(value, typeof(T));
}
catch (InvalidCastException)
{
parsedValue = null;
}
catch (ArgumentException)
{
parsedValue = null;
}
return (T)parsedValue;
}
为什么要使用财产呢?只需将类型变量设置为泛型变量的类型
public static T ToType<T>(this string value)
{
object parsedValue = default(T);
Type type = typeof(T);
try
{
parsedValue = Convert.ChangeType(value, type);
}
catch (ArgumentException e)
{
parsedValue = null;
}
return (T) parsedValue;
}
public static T ToType(此字符串值)
{
object parsedValue=默认值(T);
类型=类型(T);
尝试
{
parsedValue=Convert.ChangeType(值,类型);
}
捕获(e)
{
parsedValue=null;
}
返回(T)parsedValue;
}
用法:
myObject.someProperty = stringData.ToType<decimal>()
myObject.someProperty=stringData.ToType()
我将此用于一般转换:
public bool ConvertTo<T>(object from, out T to) {
to = default(T);
if (from is T) { to = (T)from; return true; }
Type t = typeof(T);
//TypeConverter converter = p.converter == null ? TypeDescriptor.GetConverter(t) : p.converter;
TypeConverter converter = TypeDescriptor.GetConverter(t);
if ((converter != null) && (converter.CanConvertTo(t))) {
try { to = (T)converter.ConvertTo(null, culture, from, t); return true; }
catch { }
}
try { to = (T)Convert.ChangeType(from, t, culture); return true; }
catch { }
return false;
}
public bool ConvertTo(object from, out object to, Type type) {
to = null;
if (from.GetType() == type) { to = from; return true; }
TypeConverter converter = TypeDescriptor.GetConverter(type);
if ((converter != null) && (converter.CanConvertTo(type))) {
try { to = converter.ConvertTo(null, culture, from, type); return true; }
catch { }
}
try { to = Convert.ChangeType(from, type, culture); return true; }
catch { }
return false;
}
我可以将T链接到类型参数吗?-不是直接的。您混淆了编译时和运行时。在编译代码时,C#编译器必须在处理对
ToType
的调用时决定T
是什么。每次调用ToType
时,OTOHtype
都假定一个可能不同的值。---------------------------------------------------------------\-您可以使用动态编译的一种风格,但这是一种高级技术,最好保留在少数真正需要的情况下。感谢大家的回答和输入。“专门指定类型参数”正是他在代码的第一行中所做的。这是一种使用尖括号调用语法的特殊方法,尽管它应该适用于您的情况。抱歉,Sayse。它起作用了。我把这句话漏掉了call@Sayse顺便说一句,如果T
是值类型,则无法将null
转换为T
。通常的解决方法是有两个版本的这个方法,一个用于返回aT?
的值类型,另一个用于返回T
@AntonTykhyy的引用类型-你是对的,我没有用值类型测试过这一点,尽管我不相信OP会使用它们,感谢预期的类型中有一个是decimal,我已经更新了异常路径,将parsedValue恢复为默认(T)Aha!我忘了在调用中指定T。。。ToType()!这很有效。谢谢
public bool ConvertTo<T>(object from, out T to) {
to = default(T);
if (from is T) { to = (T)from; return true; }
Type t = typeof(T);
//TypeConverter converter = p.converter == null ? TypeDescriptor.GetConverter(t) : p.converter;
TypeConverter converter = TypeDescriptor.GetConverter(t);
if ((converter != null) && (converter.CanConvertTo(t))) {
try { to = (T)converter.ConvertTo(null, culture, from, t); return true; }
catch { }
}
try { to = (T)Convert.ChangeType(from, t, culture); return true; }
catch { }
return false;
}
public bool ConvertTo(object from, out object to, Type type) {
to = null;
if (from.GetType() == type) { to = from; return true; }
TypeConverter converter = TypeDescriptor.GetConverter(type);
if ((converter != null) && (converter.CanConvertTo(type))) {
try { to = converter.ConvertTo(null, culture, from, type); return true; }
catch { }
}
try { to = Convert.ChangeType(from, type, culture); return true; }
catch { }
return false;
}
int i = 123;
string s;
if (ConvertTo<string>(i, out s) {
// use s
}