C# 通用方法返回类型作为类型参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17817407/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Generic Method Return Type as Type parameter
提问by ZuluAlphaCharlie
I have an extension method that is working ok to cast string values into various types, which looks something like this:
我有一个扩展方法可以将字符串值转换为各种类型,它看起来像这样:
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;
}
I'm unhappy about the way this looks when calling the method, however:
但是,我对调用该方法时的外观不满意:
myObject.someProperty = stringData.ToType(myObject.someProperty);
Specifying the property just to obtain the property's type seems redundant. I would rather use a signature like this:
仅仅为了获取属性的类型而指定属性似乎是多余的。我宁愿使用这样的签名:
public static T ToType<T> (this string value, Type type) { ... }
and have T end up to be the Type of type. This would make calls much cleaner:
并让 T 最终成为类型的类型。这将使调用更加清晰:
myObject.someProperty = stringData.ToType(typeof(decimal));
When I try to call this way, however, the editor complains that the return type of the extension method can't be infered from usage. Can I link T to the Type argument?
但是,当我尝试以这种方式调用时,编辑器抱怨无法从用法推断出扩展方法的返回类型。我可以将 T 链接到 Type 参数吗?
What am I missing?
我错过了什么?
Thanks
谢谢
采纳答案by Sayse
Is this what you are looking for? I've added an extra catch for cases where the cast isn't valid also
这是你想要的?我为演员也无效的情况添加了一个额外的陷阱
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;
}
Edit
编辑
a shortcut approach to fix Anton's comment
修复安东评论的捷径
if (typeof(T).IsValueType)
return default(T);
回答by McAden
Why use property at all? Just change how you're setting your type variable to the type of your generic.
为什么要使用财产?只需将您将类型变量设置为泛型类型的方式更改即可。
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;
}
Usage:
用法:
myObject.someProperty = stringData.ToType<decimal>()
回答by joe
I'm using this for a generic conversion:
我正在使用它进行通用转换:
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;
}
Before calling Convert.ChangeType
, this checks if there is a TypeConverter
for the given variable.
在调用之前Convert.ChangeType
,这会检查TypeConverter
给定变量是否存在 a 。
Call it this way:
这样称呼它:
int i = 123;
string s;
if (ConvertTo<string>(i, out s) {
// use s
}