如何为实现IEnumerable的班级解构者

发布于 2025-01-29 12:05:53 字数 1567 浏览 2 评论 0 原文

我有一个可以实现Ienumerable的课程。它包含一个实现Ienumerator的getEnumerator()方法和一个私人类。该类的Current()方法返回一个是KeyValuepair的对象,即(为了清楚地说明某些代码),

internal sealed class BlockSheet : IEnumerable
{
    public IEnumerator GetEnumerator ()
    {
        return new BlockSheetEnumerator (this);
    }

    private class BlockSheetEnumerator : IEnumerator
    {
        public object Current
        {
            get
            {
                KeyValuePair<Point, Actor> pair = (KeyValuePair<Point, Actor>)this.enumerator.Current;
                return pair;
            }
        }
    }
}

如果我按以下方式调用,则可以正常工作,

foreach (KeyValuePair<Point, Actor> unit in blocksheet)

但是如果我尝试使用Intrant KeyValuepair解剖器并写入

foreach ((Point coordinate, Actor actor) in blocksheet)

,则会得到两个错误:我得到两个错误:

错误cs1061:“对象”不包含“解构”的定义,并且可以找到一个可以找到类型'对象'的第一个参数的可访问的扩展方法'解构'(您是否缺少使用指令或汇编引用? )(CS1061)

错误CS8129:对于类型为“对象”,找不到合适的“解构”实例或扩展方法,具有2个OUT参数和一个void返回类型。 (CS8129)

(这是与 ,但我认为这不适用 - 见下文)

我会认为我会免费获得解构者。我尝试在Blocksheet类和BlockSheetEnumerator类中添加一个解构方法,但没有效果(我觉得这是有道理的,因为这两个类都没有被解构)。

我将使用Visual Studio 2019用于Mac版本8.10.22(Build 11)的Visual Studio 2019来定位.NET 5。当然,我已经成功地使用了带有词典的对象的解构器,向我自己证明这与语言/.NET版本无关。

I have a class that implements IEnumerable. It contains a GetEnumerator() method and a private class that implements IEnumerator. The Current() method of that class returns an object that is a KeyValuePair, i.e (some code elided for clarity)

internal sealed class BlockSheet : IEnumerable
{
    public IEnumerator GetEnumerator ()
    {
        return new BlockSheetEnumerator (this);
    }

    private class BlockSheetEnumerator : IEnumerator
    {
        public object Current
        {
            get
            {
                KeyValuePair<Point, Actor> pair = (KeyValuePair<Point, Actor>)this.enumerator.Current;
                return pair;
            }
        }
    }
}

This works fine if I call as follows

foreach (KeyValuePair<Point, Actor> unit in blocksheet)

but if I try to use the implicit KeyValuePair deconstructor and write

foreach ((Point coordinate, Actor actor) in blocksheet)

then I get two errors:

Error CS1061: 'object' does not contain a definition for 'Deconstruct' and no accessible extension method 'Deconstruct' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?) (CS1061)

Error CS8129: No suitable 'Deconstruct' instance or extension method was found for type 'object', with 2 out parameters and a void return type. (CS8129)

(This is the same error as, for example, Where's Deconstruct method of KeyValuePair<> struct? but I don't think that applies - see below)

I would have thought that I would get the deconstructor 'for free'. I've tried adding a Deconstruct method to both the BlockSheet class and to the BlockSheetEnumerator class, to no effect (and I don't feel like that makes sense, because neither class is being deconstructed).

I'm targeting .NET 5 with C# 9, using Visual Studio 2019 for Mac version 8.10.22 (build 11). I have, of course, successfully used a deconstructor with an object that is a Dictionary, to prove to myself that it's nothing to do with the language/.NET version.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

人心善变 2025-02-05 12:05:53

iEnumerable 表示“ 对象的收集 s”。因此,在循环内部,您在每次迭代上都会获得对象,实际上您尝试解构对象,而不是 keyvaluepair&lt; tkey,tvalue&gt; 。而且您没有适当的解构器对象

要使用解构,您需要明确和具体类型。为此,您可以:

  • 实现 iEnumerable&lt; keyvaluepair&lt; point,Actor&gt;&gt;/gt;/ienumerator&lt; keyvaluepair&lt; point&lt; point,Actor,Actor; gt;&gt;&gt; for obsoct code> code> blocksheet 。顺便说一句,实现了通用 iEnumerable&lt; t&gt; ,您可以通过通用One轻松实现非生成 iEnumerable 。

  • 只需在blocksheet.cast&lt; keyvaluepair&lt; point,actor&gt;&gt;()){/*loop hoph body*/} 中使用cast foreach(var(key,val)in blocksheet.cast.cast&lt; keyvaluepair&lt; point。但这看起来不是我的最佳选择。


  • 您还可以实现 deconstruct 对象,但是您应该弄清楚它应该如何行为对象,而其他则需要 keyvaluepair ,所以我强烈不建议这样

     公共静态类ext
      {
          公共静态空隙解构(这个对象obj,out a a,out Actor b)
          {
              如果(obj是keyvaluepair&lt; point,actor&gt; pair)
              {
                  (a,b)=对;
              }
              别的
              {
                  a = null;
                  b = null;
                  //我们可以在这里做什么?
              }
          }
      }
     

IEnumerable means "collection of Objects". So, inside the loop you got an object on each iteration and you actually try to deconstruct object, not KeyValuePair<TKey, TValue>. And you does not have appropriate deconstructor for the object.

To use a deconstruction, you need explicit and concrete type. To achieve this you can:

  • implement IEnumerable<KeyValuePair<Point, Actor>>/IEnumerator<KeyValuePair<Point, Actor>> for your object BlockSheet. By the way, having generic IEnumerable<T> implemented, you can easy implement non-generic IEnumerable via the generic one.

  • just use a cast foreach (var (key,val) in blocksheet.Cast<KeyValuePair<Point, Actor>>()){/*loop body*/}. But this does not looks like a best choice as for me.

  • you can also implement Deconstruct for Object, but you should figure out how it should behave for objects, other then desired KeyValuePair, so I strongly do not recommend this way

      public static class Ext
      {
          public static void Deconstruct(this Object obj, out Point a, out Actor b)
          {
              if(obj is KeyValuePair<Point, Actor> pair)
              {
                  (a,b)=pair;
              }
              else
              {
                  a=null;
                  b=null;
                  // what can we do here?
              }
          }
      }
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文