4
我不明白为什么C#不下面的完整情况推断类型:多个泛型类型的类型推断参数
public interface IThing {}
public class Thing1 : IThing {}
public class Thing2 : IThing {}
public interface IContainer {}
public class Container1 : IContainer
{
public IThing A { get { return new Thing1(); } }
public IThing B { get { return new Thing2(); } }
}
public class Container2 : IContainer
{
public IThing C { get { return new Thing1(); } }
public IThing D { get { return new Thing2(); } }
}
public class SomeClass
{
public void PerformTask() {}
}
public static class ExtensionMethods
{
// This function behaves as I would expect, inferring TContainer
public static TContainer DoStuffWithThings<TContainer>(this TContainer container, Func<TContainer, IThing> getSomething, Func<TContainer, IThing> getSomethingElse)
where TContainer : IContainer
{
var something = getSomething.Invoke(container);
var somethingElse = getSomethingElse.Invoke(container);
// something and something else are the things we specify in our lambda expressions with respect to the container
return container;
}
// The method in question
public static TCustomReturnType DoStuffWithThings<TContainer, TCustomReturnType>(this TContainer container, Func<TContainer, IThing> getSomething, Func<TContainer, IThing> getSomethingElse)
where TContainer : IContainer
where TCustomReturnType : new()
{
var something = getSomething.Invoke(container);
var somethingElse = getSomethingElse.Invoke(container);
// Do stuff with the things just as above
// This time we return our custom type
return new TCustomReturnType();
}
}
public class Driver
{
public static void Main(string[] args)
{
var container1 = new Container1();
var container2 = new Container2();
// I can do stuff with the things for each container, returning the container each time.
container1.DoStuffWithThings(c => c.A, c => c.B)
.DoStuffWithThings(c => c.B, c => c.A);
container2.DoStuffWithThings(c => c.C, c => c.D)
.DoStuffWithThings(c => c.D, c => c.C);
// Now we try to do the same but with the custom return type
container1.DoStuffWithThings<Container1, SomeClass>(c => c.A, c => c.B)
.PerformTask();
// As you can see, the compiler requires us to specify Container1 as the container type.
// Why is it not inferred? It is called from an instance of Container1.
// The behavior I expect is for container1.DoStuffWithThings<SomeClass>(...) to infer
// the container type and return a new instance of SomeClass.
}
}
的基本思想是,当只有一个泛型类型参数,编译器推断该类型。当我添加第二个时,编译器不会推断(它显然不能推断第二个,但我不知道为什么它不能推断第一个)。我的问题是为什么不推断容器的类型?
我不希望编译器推断第二个参数(如您所说,它不用于任何参数)。但我确实希望它能推断出第一个参数(这在参数中)。所以我可以调用container1.DoStuffWithThings(...)并推断出TContainer是Container1。进行类型推断时,参数是全部还是全无处理? –
perrick
2013-03-16 02:57:35
您必须指定* all * type参数或* none *,但请参阅我更新后的答案。 – 2013-03-16 03:05:39
谢谢。我没有意识到这是全部或没有。对于后人,我会好奇的想知道为什么;只推断已知类型和指定未知类型的设计会在哪里崩溃? – perrick 2013-03-16 03:22:25