C# c匿名对象,为什么有时只包含字段定义?

C# c匿名对象,为什么有时只包含字段定义?,c#,anonymous-types,C#,Anonymous Types,为什么我可以立即访问此处的匿名对象属性: public object ComputeStats() { var obj = new { avg = 2, hi = 3, lo = 1 }; Console.WriteLine(obj.avg); return obj; } 但此处不包括编译器错误“object”不包含

为什么我可以立即访问此处的匿名对象属性:

    public object ComputeStats()
    {
        var obj = new
        {
            avg = 2,
            hi = 3,
            lo = 1
        };

        Console.WriteLine(obj.avg);

        return obj;
    }
但此处不包括编译器错误“object”不包含“avg”的定义:

    public void DisplayStats()
    {
        object stats = ComputeStats();
        Console.WriteLine("average: " + stats.avg);
    }

一个解决方法是将stats声明为动态的,但大多数人会说只为这个对象创建一个类/类型。我更愿意使用匿名对象,但不想为了方便而开始使用dynamic。

这不是匿名类型特有的。所有内容都继承自object,这意味着您可以隐式地将任何内容转换为object

调用返回匿名类型的方法并将其分配给声明为object的变量与执行以下操作相同:

object obj = new { avg = 2, hi = 3, lo = 1 };
对象没有avg、hi等属性,所以VisualStudio不会显示它们,如果您键入它们,它们将不会编译

要说明如何使用匿名类型以外的其他类型,请执行以下操作:

var s = "Hello!";
object o = s;
只有一根绳子。s和o都表示一个字符串。但是s被转换为字符串,o被转换为对象

所以你可以这样做:

var s = "Hello!";
object o = s;
var l = s.Length;
…但你不能这样做:

var s = "Hello!";
object o = s;
var l = o.Length; // object doesn't have a Length property.
如果您这样做:

    var obj = new { avg = 2, hi = 3, lo = 1};
…使用var意味着类型是推断的。无论你给它分配什么,这就是类型。在本例中,编译器实际上是在幕后创建一个新类型,因此它的行为就像您使用这些属性定义了一个类型一样


像这样的匿名类型在方法中使用很方便,但它们并不用于在方法之间传递值。对于这一点,类、结构或元组更好。

第二个示例不是匿名对象,它只是一个没有定义属性的对象;通过使用var,您指示编译器找出obj的最佳类型,它不是object,而是dynamict。这就是我讨厌var的原因。您的问题是为什么世界是这样的?但这是你真正想要回答的问题吗?您是在寻找一种解释,说明语言是如何演变成这种形式的,还是在寻找一种更好的解决方案来解决您的问题?@elgonzo说得很清楚,var将推断类型,但它不是动态的;使用var时,类型仍然在编译时解析。例如,var x=SomeMethod;将x解析为SomeMethod声明的返回类型。我认为最后一点是,我的示例中的ComputeStats方法有一个返回类型object,这确实解释了为什么我不能只执行var stats=ComputeStats来让该类型从其他方法推断出来。这也是原因。如果一个方法返回一些东西,它必须指定返回类型,不能是匿名的。