【问题标题】:IEnumerator IEnumerable vb to C#IEnumerator IEnumerable vb 到 C#
【发布时间】:2016-08-24 09:58:54
【问题描述】:

大家好,我是 c# 语言的新手,我使用的是 vb.net, 在下面这段代码有什么错误以及为什么,谢谢

vb.net code
Class SplitString
Implements IEnumerable
Implements IEnumerator

Private currentPosition As Integer = 0
Private m_Sentence As String
Property Sentence() As String
    Get
        Return m_Sentence
    End Get
    Set(ByVal Value As String)
        m_Sentence = Value
        Me.Reset()
    End Set
End Property

Public ReadOnly Property Current As Object Implements IEnumerator.Current
    Get
        Dim counter As Integer
        Dim tmpLength As Integer = 0
        For counter = Me.currentPosition To Me.Sentence.Length - 1
            If Me.Sentence.Chars(counter) = " "c Then
                Exit For
            Else
                tmpLength += 1
            End If
        Next
        Current = Me.Sentence.Substring(Me.currentPosition, tmpLength) ' ok 
        Me.currentPosition += tmpLength + 1
    End Get
End Property

Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
    If Me.currentPosition > Me.Sentence.Length - 1 Then
        Me.Reset()
        Return False
    Else
        Return True
    End If
End Function

Public Sub Reset() Implements IEnumerator.Reset
    Me.currentPosition = 0
End Sub

Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
    Return Me
End Function
End Class

但是当我尝试这个代码到 c# 时,我得到了错误

c# code
class SplitString:IEnumerable,IEnumerator
{
    private int currentPosition = 0;
    private string m_Sentence;
    public string Sentence
    {
        get { return m_Sentence; }
        set
        {
            m_Sentence = value;
            this.Reset();
        }
    }
    public IEnumerator GetEnumerator()
    {
        return this;
    }


    public object Current
    {
        get
        {
            int counter = 0;
            int tmpLength = 0;
            for (counter = this.currentPosition; counter <= this.Sentence.Length - 1; counter++)
            {
                if (this.Sentence[counter] == ' ')
                {
                    break; 
                }
                else
                {
                    tmpLength += 1;
                }
            }
            Current = this.Sentence.Substring(this.currentPosition, tmpLength); // Error
            this.currentPosition += tmpLength + 1;
            return functionReturnValue;
        }
    }
    public bool MoveNext()
    {
       if (this.currentPosition > this.Sentence.Length-1)
       {
           this.Reset();
           return false;
       }
       else
       {
           return true;
       }
    }

    public void Reset()
    {
        this.currentPosition=0;
    }
}

错误:无法将属性或索引器“Example.splitstring.current”分配给——它是只读的

【问题讨论】:

  • 尝试用var functionReturnValue = this.Sentence.Substring...替换Current = this.Sentence.Substring...
  • @YacoubMassad 感谢 yacoub 先生,但为什么我不得不写“函数返回值”我想确切了解为什么会发生此错误
  • 有趣。我想这与 VB6 向后兼容性有关。在那里,您可以为方法名称分配一个值,而不是返回它。所以这只适用于 readonly-property-getter,没有其他地方。
  • 要在函数中设置返回值,必须使用return someValue;(也结束函数),不能将值赋给函数(老式VB习语)
  • @HansKesting:实际上你可以做到这一点。它编译并工作。但当然只在属性的 getter 中,而不是来自外部,你应该使用 Return ... 代替。

标签: c# .net vb.net vb.net-to-c#


【解决方案1】:

(出于 VB6 向后兼容性/遗留原因)VB.NET 允许您通过将 Function/Property 名称设置为一个值来从 PropertyFunction 返回值。

来自文档:Function Procedures

"... 过程以两种方式之一返回此值:..."

  • "...它为自己的函数名赋值一个或多个 程序的陈述。控制不返回调用 程序直到退出函数或结束函数语句 执行...”

例如

Public Function TestFunc() As String
    TestFunc = "bar"
    'some code
End Function

这大致相当于:

Public Function TestFunc() As String
    Dim temp = "bar"
    'some code
    Return temp
End Function

所以在您的 VB 代码中,它设置了属性名称以返回一个值:

Public ReadOnly Property Test As String
    Get
        Test = "foo"
    End Get
End Property

或者在你的情况下:

Current = Me.Sentence.Substring(Me.currentPosition, tmpLength)

在 C# 中没有与此等效的 direct,因为 return 会立即返回。最好的所以等效的 C# 将设置一个临时变量并返回:

var temp= this.Sentence.Substring(this.currentPosition, tmpLength);
//some more code
return temp;

每当我从 VB 的类中访问一个属性时,我总是在我的属性前加上 Me.,这样可以避免这种讨厌的行为

【讨论】:

    【解决方案2】:

    这个

    Current = Me.Sentence.Substring(Me.currentPosition, tmpLength) ' ok 
    

    是在不使用Return 关键字的情况下在方法中设置返回值的“旧”VB 方式。一般来说,下面的VB代码

        myMethodName = ...
        ...some other code...
    End Function
    

    可以改写为

        Dim someTempVariable = ...
        ...some other code...
        Return someTempVariable
    End Function
    

    (只要some other code 不退出方法)。

    属性也是如此。因此,我们首先将您的 VB 代码重写为 VB 代码:

            ...
        Next
        Dim returnValue = Me.Sentence.Substring(Me.currentPosition, tmpLength) 
        Me.currentPosition += tmpLength + 1
        Return returnValue
    End Get
    

    现在对 C# 的翻译应该很明显了。

    【讨论】:

      【解决方案3】:

      您还没有为Current 属性声明set 块,因此它是只读的。您需要实现它,例如:

      public object Current
      {
          get
          {
              int counter = 0;
              int tmpLength = 0;
              for (counter = this.currentPosition; counter <= this.Sentence.Length - 1; counter++)
              {
                  if (this.Sentence[counter] == ' ')
                  {
                      break; 
                  }
                  else
                  {
                      tmpLength += 1;
                  }
              }
              Current = this.Sentence.Substring(this.currentPosition, tmpLength); // Error
              this.currentPosition += tmpLength + 1;
              return functionReturnValue;
          }
          set
          {
              this.Current = value;
          }
      }
      

      【讨论】:

      • 是的,我没有为 Current 声明设置块,因为当您实现接口 IEnumerator 时,Visual Studio 将在没有设置块的情况下生成当前属性 public object Current { get { throw new NotImplementedException(); } }
      【解决方案4】:

      您的 Current 和 functionReturnValue 变量未在您的代码中定义,请在函数中定义。

         Current = this.Sentence.Substring(this.currentPosition, tmpLength); // Error
         return functionReturnValue;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-13
        • 2010-09-22
        • 2019-02-27
        相关资源
        最近更新 更多