【问题标题】:CS1674 'IEnumerator': type used in a using statement must be implicitly convertible to 'System.IDisposable'CS1674 'IEnumerator':在 using 语句中使用的类型必须隐式转换为 'System.IDisposable'
【发布时间】:2016-08-31 17:11:52
【问题描述】:

我必须在我的公司维护一个多年前使用 C# 和旧 .NET Framework(可能是 2.0?)编码的旧项目。我将旧的源文件加载到 Visual Studio,它给了我一个错误:“CS1674 'IEnumerator':在 using 语句中使用的类型必须隐式转换为 'System.IDisposable'”当我尝试构建时它。

这是一个导致此错误的完整函数,最重要的是这部分:“using (IEnumerator enumerator = dataTable.Rows.GetEnumerator())”,有什么建议可以摆脱它吗?

我试图阅读其他类似的问题,但我无法用它们解决这个问题。是否有替代方法来编写此代码,或者我的编程环境可能是导致此问题的原因?

    public void CompileDynamicCode()
    {
        base.Session.trace_enter();
        try
        {
            try
            {
                DataTable dataTable = this.ChimneyTable;
                if (dataTable.Rows.Count > 0)
                {
                    this.oChimneys = new Chimney[dataTable.Rows.Count];
                    int num = 0;

                    using (IEnumerator enumerator = dataTable.Rows.GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            DataRow dataRow = (DataRow)enumerator.Current;
                            bool entryXRight = false;
                            bool posXRight = false;
                            bool calcSteps = true;
                            bool calcCatwalk = true;
                            bool calcPlatform = true;
                            bool calcFlashing = true;
                            int connectCatwalkTo = -1;
                            if ((int)dataRow["entryXFromRight"] == 1)
                            {
                                entryXRight = true;
                            }
                            if ((int)dataRow["posXFromRight"] == 1)
                            {
                                posXRight = true;
                            }
                            if (dataTable.Columns.Contains("calcSteps") && (int)dataRow["calcSteps"] == 0)
                            {
                                calcSteps = false;
                            }
                            if (dataTable.Columns.Contains("calcCatwalk") && (int)dataRow["calcCatwalk"] == 0)
                            {
                                calcCatwalk = false;
                            }
                            if (dataTable.Columns.Contains("calcPlatform") && (int)dataRow["calcPlatform"] == 0)
                            {
                                calcPlatform = false;
                            }
                            if (dataTable.Columns.Contains("calcFlashing") && (int)dataRow["calcFlashing"] == 0)
                            {
                                calcFlashing = false;
                            }
                            if (dataTable.Columns.Contains("catwalkConnection"))
                            {
                                connectCatwalkTo = (int)dataRow["catwalkConnection"];
                            }
                            this.oChimneys[num] = new Chimney((int)dataRow["index"], (int)dataRow["shape_index"], (int)dataRow["entry_shape_index"], (int)dataRow["entryX"], entryXRight, (int)dataRow["posX"], posXRight, (int)dataRow["posY"], (int)dataRow["sizeX"], (int)dataRow["sizeY"], (int)dataRow["sizeZ"], (ChimneyAccessTypeEnum)dataRow["access_type"], calcSteps, calcCatwalk, calcPlatform, calcFlashing, connectCatwalkTo, this);
                            num++;
                        }
                        goto IL_247;
                    }
                }
                this.oChimneys = new Chimney[0];
                IL_247:
                dataTable = this.ShapeTable;
                if (dataTable.Rows.Count > 0)
                {
                    this.oShapes = new BasicShape[dataTable.Rows.Count];
                    int num2 = 0;
                    foreach (DataRow dataRow2 in dataTable.Rows)
                    {
                        this.oShapes[num2] = new BasicShape((TopRowModeEnum)dataRow2["TopRowMode"], (EaveRowModeEnum)dataRow2["EaveRowMode"], (ShapeBehaviorEnum)dataRow2["Behavior"], num2, this);
                        num2++;
                    }
                }
                dataTable = this.ConnectorTable;
                if (dataTable.Rows.Count > 0)
                {
                    this.oConnectors = new Connector[dataTable.Rows.Count];
                    int num3 = 0;
                    foreach (DataRow dataRow3 in dataTable.Rows)
                    {
                        BasicShape selectShape = null;
                        BasicShape selectShape2 = null;
                        try
                        {
                            selectShape = this.oShapes[(int)dataRow3["Shape1Index"]];
                        }
                        catch
                        {
                        }
                        try
                        {
                            selectShape2 = this.oShapes[(int)dataRow3["Shape2Index"]];
                        }
                        catch
                        {
                        }
                        this.oConnectors[num3] = new Connector((ConnectorBehaviorEnum)dataRow3["ConnectorBehavior"], selectShape, selectShape2, (ShapeConnectingLineEnum)dataRow3["Shape1Line"], (ShapeConnectingLineEnum)dataRow3["Shape2Line"], this, num3, (ConnectorStartEndMode)dataRow3["StartMode"], (ConnectorStartEndMode)dataRow3["StopMode"]);
                        num3++;
                    }
                }
            }
            catch (Exception ex)
            {
                base.Session.HandleException(ex);
                throw ex;
            }
            this.DynamicObject = this.CreateFromScript();
        }
        catch (Exception ex2)
        {
            base.Session.HandleException(ex2);
            throw ex2;
        }
        finally
        {
            base.Session.trace_exit();
        }
    }

【问题讨论】:

  • 与您的问题无关,但可以使用 int.TryParse 将空的 try 捕获替换为 if 块。

标签: c# idisposable ienumerator


【解决方案1】:

替换调用GetEnumerator():

foreach (DataRow dataRow in dataTable.Rows)
{
    bool entryXRight = false;
    // ...
}

作为旁注,该代码需要很多爱,例如将那些 throw ex; 更改为 throw; 并摆脱 goto

【讨论】:

  • 我从 1.0 的 beta 2 开始就一直在 .NET....我认为这是我第一次看到 goto(示例之外)......
  • @Tim 今天我几乎在 C++ 中使用了一个,但幸运的是找到了另一个出路。
【解决方案2】:

因为IEnumerator 本身没有实现IDisposable,所以引发了错误消息。如果您想在using 语句中使用对象,则后者是必要的,因为using 被转换为try/finally 块,并且在此finally 块中应该调用对象的IDisposable.Dispose 方法。

代码看起来很奇怪,甚至还有一个goto!但这段代码实际上做了什么

  • 如果没有行,则创建一个空的 Chimney 数组
  • 否则对行执行 foreach(执行 while (enumerator.MoveNext){} 循环内的内容)

所以可以转换成这样:

DataTable dataTable = this.ChimneyTable; 
// changes start here
this.oChimneys = new Chimney[dataTable.Rows.Count];
int num = 0;

foreach(DataRow dataRow in dataTable.Rows)
{
    // the part in the loop while (enumerator.MoveNext())
    num++; // was the last line... for orientation
}
// end of changes
IL_247: // superflous, just for your orientation

【讨论】:

  • 你甚至可以在不改变语义的情况下完全删除 if-else。
  • 在 .NET 的历史上,IEnumerator 是否曾实现过 IDisposable?我很惊讶这段代码竟然被编译了。
  • @n8wrl 也许using 模式有点不同,所以它只关心Dispose 方法是否存在,无论是来自接口还是特定类本身。
【解决方案3】:

IEnumerator 没有实现IDisposableIEnumerator<T> 可以,但那是不同的类型。

删除该行的using 部分和随附的块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多