是否可以将Type Inference用于第一个参数并指定另一个类型

时间:2011-09-16 22:06:44

标签: c# c#-3.0 extension-methods type-inference

这是一个简单的人为例子,但希望能说明我的疑问。

public class Test
{
    public string Name = "test";
}


public static class Ext 
{
     public static Test ConvertToTest<T1>(this T1 source) 
     {
         return new Test();
     }

     public static T2 Convert<T1,T2>(this T1 source) where T2 : new()
     {
         return new T2();
     }
}

ConvertToTest只需要一个Type,所以下面的编译

    Ext.ConvertToTest<string>("hello");
    "hello".ConvertToTest();

最后一个使用type-in​​terfence,这意味着它也适用于匿名类,例如

    var anon = (new { Name = "test" }) ;
    anon.ConvertToTest();

然而,这是硬编码总是使用类Test,而我希望能够在第二种方法中指定类型

我可以写

   Ext.Convert<string, Test>("hello");

并编译,因为我在编译时知道这两种类型,但是我不能将它与匿名类一起使用,而且我找不到使用类型推理和额外类型的方法

如果我可以做像

这样的事情会很好
    anon.Convert<,Test>()  ;

并且编译器将知道对第一种类型(未指定)使用推断并使用Test作为第二种类型。

有没有解决这个问题的方法?

2 个答案:

答案 0 :(得分:4)

你不能在一个方法上做你所要求的,但如果你聪明并且愿意定义几个不同的类,你应该能够像这样制作语法:

var test = Ext.Convert("hello").To<Test>();

Convert基于单个泛型类型,让它返回基于它的泛型类型:

public Converter<T> Convert<T>(T source)
{
    return new Converter<T>(source);
}

然后将一个方法添加到它返回的类型中,该方法用作原始方法的基本包装:

public class Converter<T>
{
    T _source;
    internal Converter(T source)
    {
        _source = source;
    }
    public T2 To<T2>()
    {
        return Ext.Convert<T, T2>(_source);
    }
}

答案 1 :(得分:0)

有办法做你想做的事。你使用模板模式 - 它有点像kludge,但它允许你推断这两种类型。它也可用于推断匿名类型。

这是:

public static T2 Convert<T1,T2>(this T1 source, Func<T2> template)
    where T2 : new()
{
    return new T2();
}

您可以这样称呼它:

var anon = (new { Name = "test" }) ;
anon.Convert(() => new Test());

与伪代码相距不太远。