为什么设计的匿名类型不会被方法返回?

时间:2017-03-07 22:26:00

标签: c#

在回答这个问题:Is there a way to return Anonymous Type from method?时,Andrew Hare表示

将其作为System.Object返回是从方法返回匿名类型的唯一方法。不幸的是,没有其他方法可以做到这一点,因为匿名类型是专门为防止以这种方式使用而设计的。

有人可以详细说明吗?

我的意思是C#团队可以为方法返回类型实现等效的var关键字,并根据return语句的类型键入方法。

如:

public var myMethod()
{
    var x = new {A="blah"};
    return x;
}

然后让类型推断为消费函数完成工作。

对于想要调用方法而不是链接lambdas的Linq语句(可以返回匿名类型,顺便说一句),这会有所帮助。

但显然,这是通过设计完成的。我不能看到这种权衡,有人知道吗?

3 个答案:

答案 0 :(得分:1)

这只是猜测,你说你找不到任何权衡。一个主要问题是它不能用于接口。

告诉我如何将myMethod()放在一个接口中,然后从另一个只有要引用的接口副本的程序集中使用它,并且不能引用该实现。

没有办法在接口中表示annonamous类型,并使其“使用所有公共非静态方法的接口,除了具有隐式返回类型的接口”,这将是太过分了。标准模式。

如果您使用的是C#7,则可以使用新的Tuples功能来实现类似的目标。

public (string A, int Answer) myMethod()
{
    return (A: "Blah", Answer: 42);
}

这可以与界面

一起使用
public interface IExample
{
    (string A, int Answer) myMethod();
}

答案 1 :(得分:1)

认为在给定方法体之外共享匿名类型意味着整个类型可能更多比您期望的更有用。例如,您可能希望继承它,在其上实现接口。

此外,如果您想要将匿名类型的对象转发到object以及稍后再转换为匿名类型,会发生什么?毕竟你会失去这种类型......有太多的问题需要解决,而且现在认为匿名类型就好了。

基本上这是避免将匿名类型暴露在其有限范围边界之外的原因。

实际上,一旦匿名类型内置到中间语言(IL)中,它们就是命名类型。也就是说,它是C#语法/编译器为你提供的一种语法糖,让你相信你在实例化时会创建一个类型化的对象。

理解为什么匿名类型不应该以这种方式暴露的另一种观点是,维护和发展一个强类型的代码库是很痛苦的,你需要在它上面查看进入方法体,检查整个类型的方式......

无论如何,您可能对C#7's tuples感兴趣:

public (string x, int y) DoStuff()
{
     return ("hello world", 283);
}

Aren排除了你对匿名类型的建议吗? ;)

答案 2 :(得分:0)

我认为您将运行时行为与编译时行为混淆。想象一下,如果你的代码看起来像这样:

public var myMethod(int i)
{
    if (i = 0) {
        var x = new {A="blah"};
        return x;
        }
    else {
       var a = new {K=14};
       return a;
       }
} 

在这种情况下,类型推断如何工作?它会被混淆,因为返回的类型可能是任何东西。你可以返回一个元组<>或动态类型都有利有弊。