为什么 C# 集合初始值设定项以这种方式工作? [英] Why do C# collection initializers work this way?

查看:19
本文介绍了为什么 C# 集合初始值设定项以这种方式工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究 C# 集合初始值设定项,发现它的实现非常实用,但与 C# 中的其他任何东西都非常不同

I was looking at C# collection initializers and found the implementation to be very pragmatic but also very unlike anything else in C#

我能够创建这样的代码:

I am able to create code like this:

using System;
using System.Collections;

class Program
{
    static void Main()
    {
        Test test = new Test { 1, 2, 3 };
    }
}

class Test : IEnumerable
{
    public IEnumerator GetEnumerator()
    {
        throw new NotImplementedException();
    }

    public void Add(int i) { }
}

因为我已经满足了编译器的最低要求(实现了 IEnumerable 和一个 public void Add),所以这可行,但显然没有价值.

Since I have satisfied the minimum requirements for the compiler (implemented IEnumerable and a public void Add) this works but obviously has no value.

我想知道是什么阻止了 C# 团队创建一组更严格的要求?换句话说,为什么为了编译此语法,编译器不要求类型实现 ICollection?这似乎更符合其他 C# 功能的精神.

I was wondering what prevented the C# team from creating a more strict set of requirements? In other words why, in order for this syntax to compile, does the compiler not require that the type implement ICollection? That seems more in the spirit of other C# features.

推荐答案

您的观察是正确的 - 事实上,它反映了由微软 C# 语言项目经理 Mads Torgersen 所做的观察.

Your observation is spot on - in fact, it mirrors one made by Mads Torgersen, a Microsoft C# Language PM.

Mads 于 2006 年 10 月发表了一篇关于此主题的帖子,标题为什么是集合? 他写道:

Mads made a post in October 2006 on this subject titled What Is a Collection? in which he wrote:

承认,我们一开始就搞砸了框架的版本System.Collections.ICollection,其中旁边是没用的.但我们修复了它当泛型出现时很好在 .NET 框架 2.0 中:System.Collections.Generic.ICollection允许您添加和删除元素,枚举它们,计算它们并检查会员资格.

Admitted, we blew it in the first version of the framework with System.Collections.ICollection, which is next to useless. But we fixed it up pretty well when generics came along in .NET framework 2.0: System.Collections.Generic.ICollection<T> lets you Add and Remove elements, enumerate them, Count them and check for membership.

显然从那时起,每个人都会实现 ICollection<T>每次他们制作了一个系列,对吧?不是这样.下面是我们如何使用 LINQ 来学习关于什么是真正的集合,以及这如何让我们改变我们的语言在 C# 3.0 中设计.

Obviously from then on, everyone would implement ICollection<T> every time they make a collection, right? Not so. Here is how we used LINQ to learn about what collections really are, and how that made us change our language design in C# 3.0.

事实证明,框架中只有 14 个 ICollection 实现,但有 189 个类实现了 IEnumerable 并具有公共 Add() 方法.

It turns out that there are only 14 implementations of ICollection<T> in the framework, but 189 classes that implement IEnumerable and have a public Add() method.

这种方法有一个隐藏的好处 - 如果他们基于 ICollection<T> 接口,就会有一个完全受支持的 Add() 方法.

There's a hidden benefit to this approach - if they had based it on the ICollection<T> interface, there would have been exactly one supported Add() method.

相比之下,他们采用的方法意味着集合的初始值设定项只是为 Add() 方法形成参数集.

In contrast, the approach they did take means that the initializers for the collection just form sets of arguments for the Add() methods.

为了说明,让我们稍微扩展一下您的代码:

To illustrate, let's extend your code slightly:

class Test : IEnumerable
{
    public IEnumerator GetEnumerator()
    {
        throw new NotImplementedException();
    }

    public void Add(int i) { }

    public void Add(int i, string s) { }
}

你现在可以这样写:

class Program
{
    static void Main()
    {
        Test test 
            = new Test 
            {
                1, 
                { 2, "two" },
                3 
            };
    }
}

这篇关于为什么 C# 集合初始值设定项以这种方式工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆