Элемент и этот [] - участник с таким именем уже объявлен

Возможный дубликат:
класс с индексатором и свойством названный элемент

Просто наткнулся на то, чего раньше не видел, и мне стало интересно, почему это могло происходить?

В следующем классе я получаю ошибку компилятора «Член с таким же именем уже объявлен» в отношении «Item» и «this [...]».

public class SomeClass : IDataErrorInfo 
{
    public int Item { get; set; }

    public string this[string propertyName]
    {
        get
        {
            if (propertyName == "Item" && Item <= 0)
            {
                return "Item must be greater than 0";
            }
            return null;
        }
    }

    public string Error
    {
        get { return null; }
    }
}

Компилятор, кажется, думает, что этот [...] и Item используют одно и то же имя члена. Это правильно / нормально? Я удивлен, что не сталкивался с этим раньше.


person Mike Rowley    schedule 15.07.2011    source источник
comment
Это дубликат. См. Ответ на этот вопрос SO: stackoverflow.com/questions/5110403/.   -  person Philipp Schmid    schedule 16.07.2011


Ответы (4)


Когда вы определяете индексатор следующим образом:

this[string propertyName]

Он скомпилирован в свойство .Item.

Вы можете исправить это с помощью атрибута [System.Runtime.CompilerServices.IndexerName("NEW NAME FOR YOUR PROPERTY")] вашего индексатора.

person VMAtm    schedule 15.07.2011

Ага. this[] компилируется до свойства, называемого Item по умолчанию. Вы можете изменить это с помощью атрибута System.Runtime.CompilerServices.IndexerName. (ссылка MSDN)

person dlev    schedule 15.07.2011

Это нормально. В языке C # есть ключевое слово this, которое используется для объявления индексаторов, но в скомпилированном классе метод get для индексатора будет называться get_Item (что является межъязыковым соглашением в .NET). Поскольку компилятор хочет дать то же имя получателю для вашего свойства Item, он сообщает об ошибке.

person Kevin Watkins    schedule 15.07.2011

Если вы посмотрите на интерфейс IDataErrorInfo с кодом IL, вы увидите

.class public interface abstract auto ansi IDataErrorInfo
{
    .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = { string('Item') }
    .property instance string Error
    {
        .get instance string System.ComponentModel.IDataErrorInfo::get_Error()
    }

    .property instance string Item
    {
        .get instance string System.ComponentModel.IDataErrorInfo::get_Item(string)
    }

}

что переводится в C # на

public interface IDataErrorInfo
{
    // Properties
    string Error { get; }
    string this[string columnName] { get; }
}

Итак, причина в том, что C # скрывает от вас какое-то специальное имя метода за синтаксисом this, которое противоречит реальному имени метода, используемому CLR.

person Alois Kraus    schedule 15.07.2011