请考虑以下MCVE:
using System;
public interface IThing { }
public class Foo : IThing
{
public static Foo Create() => new Foo();
}
public class Bar : IThing
{
public static Bar Create() => new Bar();
}
public delegate IThing ThingCreator();
class Program
{
static void Test(ThingCreator creator)
{
Console.WriteLine(creator.Method.ReturnType);
}
static void Main()
{
Test(Foo.Create); // Prints: Foo
Test(Bar.Create); // Prints: Bar
Test(() => new Foo()); // Prints: IThing
Test(() => new Bar()); // Prints: IThing
}
}
为什么反射静态工厂方法的返回类型会给出具体的类型,而内联调用构造函数会给出接口?我希望它们都是一样的。
另外,有没有办法在lambda版本中指定我希望返回值为具体类型?或者调用静态方法是唯一的方法吗?
发布于 2017-03-17 06:54:40
lambda表达式的返回类型不是从lambda实际返回的内容中推断出来的,而是从它被赋值到的类型中推断出来的。也就是说,您不能像这样分配lambda (除非涉及到泛型类型参数;请参阅Eric Lippert的注释):
// This generates the compiler error:
// "Cannot assign lambda expression to an implicitly-typed variable".
var lambda = () => new Foo();
您必须始终执行以下操作(lambda始终分配给委托类型):
Func<MyType> lambda = () => new Foo();
因此,在Test(() => new Foo());
中,lambda的返回类型是由它所赋给的参数类型决定的(IThing
,ThingCreator
的返回类型)。
在Test(Foo.Create);
中,您根本没有lambda,而是一个声明为public static Foo Create() ...
的方法。在这里,类型是显式指定的,并且是Foo
(它是静态方法还是实例方法没有区别)。
发布于 2017-03-17 06:45:36
我个人的猜测是调用的位置。当您将() => new Foo()
传递给该函数时,它会将其作为ThingCreator
获取并调用它来获取IThing
。但是,当您在测试方法调用具体类型的工厂方法时将其发送到Test
方法时,它将转到具体类型的Create()
,后者又返回完全可接受的具体对象,因为它也是IThing
不过,我想你需要的比我猜的要多。如果我错了,很抱歉!
https://stackoverflow.com/questions/42846004
复制相似问题