使用泛型方法,是否有可能从相同的方法获取不同的类型?

问题描述:

我能有这样的事情:使用泛型方法,是否有可能从相同的方法获取不同的类型?

int x = MyMethod<int>(); 
string y = MyMethod<string>(); 

所以,一个方法返回基于T.当然,不同类型,会有里面的方法逻辑,以确保它返回正确的事情。

我永远无法得到像这样的东西来运行。它抱怨说,它不能返回值转换为T:

public static T MyMethod<T>() 
{ 
    if(typeof(T) == typeof(Int32)) 
    { 
    return 0; 
    } 
    else 
    { 
    return "nothing"; 
    } 
} 
+4

˚F首先,这段代码不会编译,因为没有指定返回类型。我假设你想要它读取'公共静态T MyMethod ()' – Nick 2010-01-22 21:51:44

+0

作为你的答案,尼克。我认为这是他需要的解决方案。 – JMD 2010-01-22 21:53:21

+0

...虽然上面编写的代码仍然不会编译,因为“Nothing”不是T,除非T是字符串,并且0不是T,除非T是数字类型。 – JMD 2010-01-22 21:54:53

请尝试以下

public static T MyMethod<T>() { 
    if (typeof(T) == typeof(Int32)) { 
    return (T)(object)0; 
    } else { 
    return (T)(object)"nothing"; 
    } 
} 

这里的窍门是铸造object。你试图做的事情本质上是不安全的,因为编译器不能推断0或“无”可转换为任何给定的T。毕竟它是无限的。所以,只需告诉编译器将其转换为object并不安全。

+0

这个工程。所以,唯一觉得你做得不同的事情是先把它投射到一个物体上,然后再投射到T? – Deane 2010-01-22 22:03:34

+1

虽然这解决了编译时错误,但它仍然没有意义。如果T是一个页面类型,那么通过这个(对象)hack将一个字符串转换为T是没有意义的。这个编译的唯一原因是因为字符串和整数都可以转换为对象,并且对象可以是它们的后代类型(即所有内容)的大小写。 – 2010-01-22 22:17:08

如果你想要返回一个“null”类型的值,如果它不是int,你可以这样做。但是如果你想在所有其他情况下使用字符串,请检查其他答案。

public static T MyMethod<T>() 
{ 
    if(typeof(T) == typeof(Int32)) 
    { 
    return (T)(object)0; 
    } 
    else 
    { 
    return default(T); // or null 
    } 
} 
+0

对于字符串示例,OP希望它返回特定的字符串值,而不是默认值(T)。您也缺少返回类型。 – JaredPar 2010-01-22 21:56:11

+0

真..我错过了它,因为我复制了代码,并在编辑之前错过了那部分。 – 2010-01-22 21:59:57

+0

这将不起作用 - int和T之间没有转换 – Lee 2010-01-22 22:00:34

@Nick在他的评论中是正确的,你的代码不会编译。但是,假设你的意思:

public static T MyMethod<T>() 
{ 
    if(typeof(T) == typeof(Int32)) 
    { 
    return 0; 
    } 
    else 
    { 
    return "nothing"; 
    } 
} 

它可能会非常棘手,使仿制药非一般像你正试图(和真正违反整点),但这应该工作:

public static T MyMethod<T>() 
{ 
    if(typeof(T) == typeof(Int32)) 
    { 
    return (T)(object)0; 
    } 
    else if(typeof(T) == typeof(string)) 
    { 
    return (T)(object)"nothing"; 
    } 

    return default(T); 
} 
+0

是的,这是与上述相同的解决方案。我假设我不得不首先投射到一个对象,因为没有从int到T的直接投射。但是有一个从int到object的对象,并且对象是T.是否正确? – Deane 2010-01-22 22:08:52

+0

因为您检查typeof(T)是。真的else子句应该检查typeof(字符串),否则像MyMethod 会失败。我将编辑示例。 – dkackman 2010-01-22 23:12:10

这ISN” t有效,因为不能保证T可以被转换/可转换为字符串或int。泛型不是变体 - 即可以容纳任何东西的类型 - 它们被编译时解析为真实类型。你的代码不会编译,因为它不应该。您可以使用这里发布的一些黑客来解决编译时问题,但这确实是一个逻辑问题。退后一步,重新思考你想要做什么,而不是试图绕过编译器。

+0

我可以以某种方式约束T只能是字符串或整型? – Deane 2010-01-22 23:06:57

+0

@Deane - 你不能 – dkackman 2010-01-22 23:15:24

+0

@Deane - 在VB或类似的脚本语言中,你可以从函数返回你想要的任何东西 - int,string,float,page,webservice reference,你有什么。在强类型语言中,情况并非如此 - 因为编译器希望你控制统治,而不是让它为你做你的工作。 CALLING CODE看起来像你需要这种结果?! – 2010-01-23 05:44:08

稍微偏离主题,但如果你试图做这件事情那么它可能是你的设计是错误的...

为什么不超载的方法和结果设置为出放慢参数:

void MyMethod(out int result) 
{ 
    result=0; 
} 

void MyMethod(out string result) 
{ 
    result="my value"; 
} 

然后你就可以说:

int value; 
MyMethod(out value); 

,编译器将选择合适的版本

+0

对于不同类型使用相同的逻辑,它不是正确使用泛型吗?我只是有一个方法,有一堆逻辑,但在不同的情况下,我需要不同的类型。这不是使用泛型的正确方法吗? – Deane 2010-01-22 22:46:07

+0

但是你正在切换类型,这会导致问题...我会发布一个替代 – Sean 2010-01-22 22:47:45

+0

是的,这将工作。看起来不那么优雅,因为我现在有三种方法 - 每种类型一种,核心逻辑一种。为什么打开键入问题? – Deane 2010-01-22 22:57:48