我有一个可以实现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.
发布评论
评论(1)
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
,所以我强烈不建议这样IEnumerable
means "collection ofObject
s". So, inside the loop you got anobject
on each iteration and you actually try to deconstruct object, notKeyValuePair<TKey, TValue>
. And you does not have appropriate deconstructor for theobject
.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 objectBlockSheet
. By the way, having genericIEnumerable<T>
implemented, you can easy implement non-genericIEnumerable
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
forObject
, but you should figure out how it should behave for objects, other then desiredKeyValuePair
, so I strongly do not recommend this way