C#中的语法启用模式是什么?

C#中的语法启用模式是什么?,c#,c#-5.0,C#,C# 5.0,C#语言有几个模式特征,即类不需要从特定接口派生;而是实现某种模式,以参与一些C#语法/特性 让我们考虑一个例子: public class MyCollection : IEnumerable { public T Add(T name, T name2, ...) { } public IEnumerator GetEnumerator() { return null; } } 这里,TYPE是任何类型。基本上,我们有一个类实现了IEnumerable,并有一个名为Add(

C#语言有几个模式特征,即类不需要从特定接口派生;而是实现某种模式,以参与一些C#语法/特性

让我们考虑一个例子:

public class MyCollection : IEnumerable
{
    public T Add(T name, T name2, ...) { }
    public IEnumerator GetEnumerator() { return null; }
}
这里,
TYPE
是任何类型。基本上,我们有一个类实现了
IEnumerable
,并有一个名为
Add()
的方法,该方法具有任意数量的参数

这将启用新的
MyCollection
实例的以下声明:

new MyCollection{{a1, a2, ...}, {b1, b2, ...} }
这相当于:

var mc = new MyCollection();
mc.Add(a1, a1, ...);
mc.Add(b1, b2, ...);
魔法与此同时,最近(我相信在构建事件期间)Anders Hejlsberg透露,新的
wait/async
也将使用模式来实现,这让WinRT可以不返回
任务
以外的内容

所以我的问题是双重的

  • 安德斯所说的模式是什么,还是我误解了什么?答案应该介于WinRT提供的类型、类似于
    IAsyncFoo
    的内容和未发布的规范之间
  • 在C#中是否还有其他类似的模式(可能已经存在)

  • 对于
    async
    ,它适用于等待者模式,我认为:

    “语言支持等待任何公开正确方法(实例方法或扩展方法)的实例:GetAwaiter。GetAwaiter需要返回一个本身公开三个成员的类型:”

    例如,在异步CTP中,Task的GetAwaiter方法返回TaskAwaiter类型的值:

    public struct TaskAwaiter 
    { 
        public bool IsCompleted { get; }
        public void OnCompleted(Action continuation); 
        public void GetResult(); 
    }
    
    如果需要
    async
    的所有详细信息,请启动。他们详细讨论了这个问题


    除了集合初始值设定项(正如您所提到的基于模式)之外,C#中另一个基于模式的特性是LINQ:对于LINQ关键字,所需的只是重载解析找到具有正确名称和签名的实例或扩展方法。看一看。另外,
    foreach
    是基于模式的-Eric还在链接文章中描述了关于此模式的详细信息。

    规范草案已经发布-您可以从下载。异步模式是在driis的回答中给出的——您也可以阅读我的文章,了解更多关于该模式的详细信息

    请注意,此模式仅适用于“您可以等待的”。异步方法必须返回
    void
    Task
    Task

    对于C#中除您最初提到的集合初始值设定项之外的其他模式:

    • foreach
      可以迭代非IEnumerable实现,只要该类型有一个
      GetEnumerator
      方法,该方法返回的类型具有
      MoveNext()
      Current
      成员
    • 解析调用
      选择
      其中
      分组依据

    您可以使用的另一种模式是using关键字。 如果您有一个实现了
    IDisposable
    的类,那么您可以说:

    using(Resource myResource = GetResource())
    {
    }
    
    也就是说,类似于:

    Resource myResource;
    try
    {
         myResource = GetResource();
    }
    finally
    {
         var disposable = myResource as IDisposable;
         if(disposable != null) disposable.Dispose()
    }
    
    虽然我认为它不如
    foreach
    或查询操作符那么“神奇”,但它是一种相对不错的语法

    同样,您也可以使用
    yield return
    自动实现迭代器

    public struct SimpleBitVector32 : IEnumerable<bool>
    {
    
        public SimpleBitVector32(uint value)
        {
            this.data = value;
        }
    
        private uint data; 
        public bool this[int offset]
        {
            get
            {
                unchecked
                {
                    return (this.data & (1u << offset)) != 0;
                }
            }
            set
            {
                unchecked
                {
                    this.data = value ? (this.data | (1u << offset)) : (this.data & ~(1u << offset));
                }
            }
        }
    
        public IEnumerator<bool> GetEnumerator()
        {
            for (int i = 0; i < 32; i++)
            {
                yield return this[i];
            }
        }
    
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }
    
    public结构SimpleBitVector32:IEnumerable
    {
    公共SimpleBytVictor 32(uint值)
    {
    这个数据=值;
    }
    私有uint数据;
    公共布尔本[int offset]
    {
    得到
    {
    未经检查
    {
    
    返回(这是数据和(1u你可能应该看看Jon Skeet的博客,看看异步功能是如何工作的。他对异步功能进行了深入的研究,主要是展示了你如何/可以/自己实现异步功能。不确定你是否读过这篇博文,但你可能会发现它很有趣。谢谢Jon,你认为这是这些功能的完整列表吗?+1!你说得对对于using语句,magic-wise,尽管出于某种原因我不想承认。我认为这是因为界面让它有点不那么神奇:)
    public struct SimpleBitVector32 : IEnumerable<bool>
    {
    
        public SimpleBitVector32(uint value)
        {
            this.data = value;
        }
    
        private uint data; 
        public bool this[int offset]
        {
            get
            {
                unchecked
                {
                    return (this.data & (1u << offset)) != 0;
                }
            }
            set
            {
                unchecked
                {
                    this.data = value ? (this.data | (1u << offset)) : (this.data & ~(1u << offset));
                }
            }
        }
    
        public IEnumerator<bool> GetEnumerator()
        {
            for (int i = 0; i < 32; i++)
            {
                yield return this[i];
            }
        }
    
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }