我知道typeof(T),但编译器没有。怎么修?

时间:2009-06-23 10:39:34

标签: c# generics

我正在尝试编写一个这样的方法:

public static T Test<T>()
{
  if (typeof(T)==typeof(string))
     return "1241";

  // do something else
}

但我似乎无法弄清楚如何将其拉下来。我想根据调用方法的T类型返回值。我需要返回字符串,int,自定义类,List等。

实际的用例是一些自定义序列化代码,其中反序列化代码必须知道它应该生成的对象的类型。

澄清: 上面的示例给出以下错误: 无法将字符串转换为类型T

理想的解决方案适用于值类型和引用类型,并且不包含用于重载解析的虚拟参数。

我开始怀疑是否存在理想的解决方案。

谢谢卢卡斯

7 个答案:

答案 0 :(得分:13)

object的中间演员并不理想,但是这样的事情可以解决这个问题:

public static T Test<T>()
{
    if (typeof(T) == typeof(string))
        return (T)(object)"1241";

    // do something else
}

答案 1 :(得分:6)

您必须将返回值强制转换为T,例如这样的参考类型:

public static T Test<T>() where T : class
{
  if (typeof(T)==typeof(string))
     return "1241" as T;

  return default(T);
}

答案 2 :(得分:5)

<强>当心!下面的解决方案工作(使用Mono gmcs C#编译器验证)。

但是,通过我读取C#标准来工作,因为重载决策应尽可能支持非泛型版本的方法。 ECMA-334的相关部分是25.1.7:“泛型类中的重载”。此外,Eric Lippert似乎也在blog posting中这么说。

反馈将不胜感激:为什么这不能按预期工作?


您有不相关的类型和不相关的行为:此代码尖叫“使用重载!”

泛型适用于不相关的类型,但相同(或高度相似)的行为。

执行此操作(完成测试程序以重现行为):

using System;

class TestClass {
    public static T Test<T>() {
        return TestWith(default(T));
        // do something else
    }

    public static string TestWith(string dummy) {
        // Used only for `string`.
        return "string";
    }

    public static T TestWith<T>(T dummy) {
        // Used for everything else.
        return dummy;
    }

    static void Main() {
        Console.WriteLine("Expected \"0\", got \"{0}\"", Test<int>());
        Console.WriteLine("Expected \"string\", got \"{0}\"", Test<string>());
    }
}

使用gmcs编译,产生:

Expected "0", got "0"
Expected "string", got ""

此处,该参数仅用于消除重载呼叫的歧义。这里不能使用显式通用参数,因为其中一个函数(string特化)不是通用的。

答案 3 :(得分:2)

尝试

public static T Test<T>() where T : class
{
  if (typeof(T) == typeof(string)) return "asdf" as T;  // do something else
  // do something else        
}

答案 4 :(得分:1)

您可以使用ChangeType吗?

public static T Test<T>()
{
    if (typeof(T)==typeof(string))
        return (T)Convert.ChangeType("1234", typeof(T), CultureInfo.InvariantCulture);
    return default(T);
}

答案 5 :(得分:0)

我找到了解决方案:

public static T Test<T>()
{
  if (typeof(T) == typeof(string))
     return (T)(object)"1241";    // this works.

    // do something else
}

感谢所有答案。

答案 6 :(得分:0)

public static T Test<T>()
{
  if (typeof(T)==typeof(string))
     return (T)Convert.ChangeType("1241", typeof(T));

  return default(T);
}

我没有测试过它: - )