【问题标题】:Error: '<method1>' and '<method2>' cannot overload each other错误:“<method1>”和“<method2>”不能互相重载
【发布时间】:2010-04-30 11:05:54
【问题描述】:

我在 VB 中覆盖了一个列表。

在 C# 中,代码编译后如下所示:

class MyObjectCollection : IList
{
    ...
    /// <summary>
    /// Gets or sets the element at the specified index.
    /// </summary>
    public MyObject this[int index]
    {
        get { return (MyObject)innerArray[index]; }
        set { innerArray[index] = value; }
    }
    ...
}

在VB.NET中我转换:

Class MyObjectCollection
    Implements IList        
    ...

    ''' <summary> '
    ''' Gets or sets the element at the specified index. '
    ''' </summary> '
    Default Public Overrides Property Item(ByVal index As Integer) As MyObject
      Get
        Return DirectCast(innerArray(index), MyObject)
      End Get
      Set(ByVal value As MyObject)
        innerArray(index) = value
      End Set
    End Property
    ...
End Class

错误:

'公共覆盖默认属性 项目(索引为整数)作为 MyObject' 和'公共默认财产 项目(索引为整数)作为对象' 不能互相超载,因为 它们仅在返回类型上有所不同

C# 中的整个集合类

public class MyObjectCollection : IList
{
    private ArrayList innerArray;

    public MyObjectCollection()
    {
        innerArray = new ArrayList();
    }

    public int Count
    {
        get { return innerArray.Count; }
    }

    public bool IsFixedSize
    {
        get { return false; }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public bool IsSynchronized
    {
        get { return false; }
    }

    object ICollection.SyncRoot
    {
        get { return null; }
    }

    public MyObject this[int index]
    {
        get { return (MyObject)innerArray[index]; }
        set { innerArray[index] = value; }
    }

    public int Add(MyObject value)
    {
        int index = innerArray.Add(value);

        return index;
    }

    public void AddRange(MyObject[] array)
    {
        innerArray.AddRange(array);
    }

    public void Clear()
    {
        innerArray.Clear();
    }

    public bool Contains(MyObject item)
    {
        return innerArray.Contains(item);
    }

    public bool Contains(string name)
    {
        foreach (MyObject spec in innerArray)
            if (spec.Name == name)
                return true;

        return false;
    }

    public void CopyTo(MyObject[] array)
    {
        innerArray.CopyTo(array);
    }

    public void CopyTo(MyObject[] array, int index)
    {
        innerArray.CopyTo(array, index);
    }

    public IEnumerator GetEnumerator()
    {
        return innerArray.GetEnumerator();
    }

    public int IndexOf(MyObject value)
    {
        return innerArray.IndexOf(value);
    }

    public int IndexOf(string name)
    {
        int i = 0;

        foreach (MyObject spec in innerArray)
        {
            if (spec.Name == name)
                return i;

            i++;
        }

        return -1;
    }

    public void Insert(int index, MyObject value)
    {
        innerArray.Insert(index, value);
    }

    public void Remove(MyObject obj)
    {
        innerArray.Remove(obj);
    }

    public void Remove(string name)
    {
        int index = IndexOf(name);
        RemoveAt(index);
    }

    public void RemoveAt(int index)
    {
        innerArray.RemoveAt(index);
    }

    public MyObject[] ToArray()
    {
        return (MyObject[])innerArray.ToArray(typeof(MyObject));
    }

    #region Explicit interface implementations for ICollection and IList
    void ICollection.CopyTo(Array array, int index)
    {
        CopyTo((MyObject[])array, index);
    }

    int IList.Add(object value)
    {
        return Add((MyObject)value);
    }

    bool IList.Contains(object obj)
    {
        return Contains((MyObject)obj);
    }

    object IList.this[int index]
    {
        get
        {
            return ((MyObjectCollection)this)[index];
        }
        set
        {
            ((MyObjectCollection)this)[index] = (MyObject)value;
        }
    }

    int IList.IndexOf(object obj)
    {
        return IndexOf((MyObject)obj);
    }

    void IList.Insert(int index, object value)
    {
        Insert(index, (MyObject)value);
    }

    void IList.Remove(object value)
    {
        Remove((MyObject)value);
    }
    #endregion
}

【问题讨论】:

  • C# 代码示例无法为我编译,与您从 VB.net 编译器获得的错误基本相同。你能发布整个 C# 课程吗?

标签: c# .net vb.net


【解决方案1】:

我建议从CollectionBase 继承,它专门用于创建强类型集合。

Public Class MyObjectCollection
   Inherits CollectionBase

查看example

【讨论】:

    【解决方案2】:

    Reflector 告诉我你可能试试:

    Private Property System.Collections.IList.Item(ByVal index As Integer) As Object
        Get
            Return Me.Item(index)
        End Get
        Set(ByVal value As Object)
            Me.Item(index) = DirectCast(value, MyObject)
        End Set
    End Property
    
    Public Default Property Item(ByVal index As Integer) As MyObject
        Get
            Return DirectCast(Me.innerArray.Item(index), MyObject)
        End Get
        Set(ByVal value As MyObject)
            Me.innerArray.Item(index) = value
        End Set
    End Property
    

    但不能保证。

    【讨论】:

    • 不起作用:错误:“具有相同签名的多个定义”。
    【解决方案3】:

    如果我正确理解了这个问题,你目前有这样的方法:

    Public Overrides Property Item(ByVal index As Integer) As MyObject
      Get
        Return DirectCast(innerArray(index), MyObject)
      End Get
      Set(ByVal value As MyObject)
        innerArray(index) = value
      End Set
    End Property
    

    您还有一个实现 IList 接口的方法,如下所示:

    Public Property Item(ByVal index As Integer) As Object Implements IList.Item
        Get
            Return DirectCast(innerArray(index), MyObject)
        End Get
        Set(ByVal value As Object)
            innerArray(index) = value
        End Set
    
    End Property
    

    这不起作用,因为方法名称相同,但返回类型不同。您需要做的是更改 IList 实现方法的名称。

    尝试类似:

    Public Property IList_Item(ByVal index As Integer)As Object Implements IList.Item
        Get
            Return DirectCast(innerArray(index), MyObject)
        End Get
        Set(ByVal value As Object)
            innerArray(index) = value
        End Set
    
    End Property
    

    【讨论】:

    • 甚至可能更好 Private 属性 IList_Item ... 实现 IList.Item
    【解决方案4】:

    编辑:完整的课程表明,在 C# 版本中,您有两个索引器。一个被声明为 IList 索引器的显式实现:

    object IList.this[int index] 
    { 
        get 
        { 
            return ((MyObjectCollection)this)[index]; 
        } 
        set 
        { 
            ((MyObjectCollection)this)[index] = (MyObject)value; 
        } 
    } 
    

    这就是为什么你也可以有一个类型化的索引器,它只在返回类型上有所不同。

    您需要在 VB.net 中做同样的事情,但我的 VB.net 技能无法胜任这项工作 - 我看不出如何在 VB.net 中进行显式接口实现。

    或者,您需要使用 IList 的通用版本来拥有一个特定类型的索引器。这是 C# 版本:

        class MyObjectCollection : IList<MyObject>
        {
            private readonly MyObject[] innerArray;
    
            public MyObject this[int index] 
            { 
                get { return (MyObject)innerArray[index]; } 
                set { innerArray[index] = value; } 
            } 
        } 
    

    【讨论】:

    • 我的理解是问题出在VB,而不是C#
    • 已编辑问题中显示的完整 C# 类解释了它为何在 C# 中工作。如果显式接口实现可以在 VB.net 中完成,那么这也是解决方案。
    • 在 VB 中,所有接口都明确实现。没有隐式实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-23
    相关资源
    最近更新 更多