【问题标题】:What C# feature allows the use of an "object literal" type notation?什么 C# 功能允许使用“对象文字”类型表示法?
【发布时间】:2012-04-25 08:27:02
【问题描述】:

我来自 JavaScript,我知道 { } 是一个对象字面量,不需要 new Object 调用;我想知道 {"id",id}, {"saveChangesError",true} 部分中的 C# 是否相同。

我知道这里有两个 C# 功能,愿意向我解释一下它们是什么吗?

new RouteValueDictionary()
{ //<------------------------------[A: what C#  feature is this?] -------||
   {"id",id}, //<------------------[B: what C# feature is this also?]    ||
   {"saveChangesError",true}                                             ||
}); //<------------------------------------------------------------------||

【问题讨论】:

  • 在 C# 中自动调用某些方法(尤其是 Add)是一种特殊的魔法,对象被创建之后。
  • 回答者:属性初始化可以和集合初始化混用吗? (这应该在解释“外部”构造时出现,因为它可能是:new Foo { Bar = Quz }。)
  • @pst:不,甚至在 VB.NET 中也没有,奇怪的是......

标签: c# asp.net-mvc dictionary routevalues


【解决方案1】:

这是一个单一的功能 - collection initializers。像对象初始化器一样,它只能用作对象初始化表达式的一部分,但基本上它调用 Add 时使用任何参数 - 使用大括号指定多个参数,或一次指定单个参数而无需额外的大括号,例如

var list = new List<int> { 1, 2, 3 };

有关详细信息,请参阅 C# 4 规范的第 7.6.10.3 节。

请注意,编译器需要两种类型的东西才能用于集合初始化器:

  • 它必须实现IEnumerable,尽管编译器不会生成任何对GetEnumerator 的调用
  • Add 方法必须具有适当的重载

例如:

using System;
using System.Collections;

public class Test : IEnumerable
{
    static void Main()
    {
        var t = new Test
        {
            "hello",
            { 5, 10 },
            { "whoops", 10, 20 }
        };
    }

    public void Add(string x)
    {
        Console.WriteLine("Add({0})", x);
    }

    public void Add(int x, int y)
    {
        Console.WriteLine("Add({0}, {1})", x, y);
    }

    public void Add(string a, int x, int y)
    {
        Console.WriteLine("Add({0}, {1}, {2})", a, x, y);
    }

    IEnumerator IEnumerable.GetEnumerator()        
    {
        throw new NotSupportedException();
    }
}

【讨论】:

  • 让我们至少在答案中有一个指向 MSDN 文档的链接。 :)
  • @DanJ:是的,我快到了:)
  • @JonSkeet 应用敏捷原则回答 StackOverflow 问题,嗯?唔。 ;)
【解决方案2】:

这就是集合初始化语法。这个:

RouteValueDictionary d = new RouteValueDictionary()
{                             //<-- A: what C#  feature is this?
   {"id",id},                 //<-- B: what C# feature is this also?    
   {"saveChangesError",true}
});

基本上相当于这个:

RouteValueDictionary d = new RouteValueDictionary();
d.Add("id", id);
d.Add("saveChangesError", true);

编译器认识到它实现了IEnumerable 并具有适当的Add 方法并使用它。

见:http://msdn.microsoft.com/en-us/library/bb531208.aspx

【讨论】:

  • “字典初始化语法”听起来像是 C#作为一种语言 具有内置的字典知识。它没有。它适用于实现IEnumerable 并具有适当Add 方法的any 类型。
  • @JonSkeet:它是如何识别出KeyValuePair这一事实的?
  • @minitech:没有。它认识到存在Add(key, value) 方法这一事实。有关此示例,请参阅我的答案。另请注意,实际上,该变量仅在 Add 调用之后分配 - 就好像您在此之前有一个临时变量一样。
  • 请允许我写这篇评论 :) (@edit:这就是我说“基本上”的原因)
  • 是的,Jon Skeet 显然没有我写 4 段评论然后决定删除最后 3 段作为多余的问题。
【解决方案3】:

请看Annonymous Types 它们允许您执行以下操作:

var v = new { Amount = 108, Message = "Hello" };  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-08
    • 1970-01-01
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多