Почему я не могу переопределить и создать новое свойство (C #) одновременно? - PullRequest
1 голос
/ 24 марта 2010

Согласно этот вопрос кажется, что вы можете сделать это для методов. Я хочу знать, почему он не работает, когда я пробую его со свойствами.

public class Foo
{
    public virtual object Value
    {
        get;
        set;
    }
}

public class Foo<T> : Foo
{
    public override object Value
    {
        get
        {
            return base.Value;
        }
        set
        {
            base.Value = (T)value; //inject type-checking on sets
        }
    }

    public new T Value
    {
        get { return (T)base.Value; }
        set { base.Value = value; }
    }
}

Сообщение об ошибке из C # 4.0 RC1

Ошибка 1 Тип ClassLibrary1.Foo уже содержит определение «Значение» ClassLibrary1 \ Class1.cs 31 22 ClassLibrary1

Ответы [ 6 ]

4 голосов
/ 24 марта 2010

У вас не может быть двух свойств, использующих одно и то же имя.Это не разрешено в C #.Единственное исключение - это индексаторы, поскольку в случае индексатора сигнатура изменяется в зависимости от типа индекса.

Нельзя перегрузить метод, который отличается только типом возвращаемого значения.Свойство с одним именем в основном запрещено тем же правилом, поскольку внутренне это пара методов без аргументов для метода доступа get.

3 голосов
/ 24 марта 2010

Вы можете сделать это, если сделаете что-то вроде следующего ...

public interface IFoo<T>
{
    T Value { get; set; }
}

public class Foo<T> : Foo, IFoo<T>
{
    T IFoo.Value
    {
        get { return (T)base.Value; }
        set { base.Value = value; }
    }
}

Единственное, с чем это связано, - когда вы ссылаетесь, вы должны использовать интерфейс типа ... т.е.

   IFoo<int> myfoo = new Foo<int>();
   int result = myFoo.Value;    //This will give you the typed version

   Foo<int> myfoo = new Foo<int>();
   int result = myFoo.Value;    //This will give throw an exception
2 голосов
/ 24 марта 2010

C ++ / CLI может сделать это, даже если C # не может. В C ++ / CLI вы можете явно указать, какой метод переопределяется, поэтому имена не должны совпадать.

1 голос
/ 24 марта 2010

Основная проблема заключается в том, что никогда не известно, какое свойство использовать.

например,

Foo<int> s = new Foo<int>();

s.Value = "hmmm";

Так какое свойство следует использовать? int происходит от объекта, а также отвечает ограничениям версии общего свойства.

1 голос
/ 24 марта 2010

Вы можете достичь этого с помощью взаимодействия.

public interface IFoo
{
    object Value { get; set; }
}

public class Foo<T> : IFoo
{
    object _value = null;
    object IFoo.Value
    {
        get { return _value; }
        set { _value = value; }
    }

    public T Value
    {
        get;
        set;
    }
}
0 голосов
/ 24 марта 2010

У вас есть два определения одного и того же свойства Value одно определено переопределением ... и одно новым. Тип возврата не является отличительным признаком в сигнатуре метода, т. Е. Если сигнатура отличается только типом возвращаемого значения, сигнатура считается одинаковой. Итак, используйте переопределение или новый.

В вашем случае вы можете использовать new вместо override для достижения цели. Однако при использовании new вы всегда должны учитывать, что реализованная реализация зависит от типа, для которого вы вызываете метод. * Т.е. 1004 *

var foo = new Foo();
var foo_ = new Foo<string>();

foo.Value            // calls the implementation on Foo 
foo_.Value           // calls the implementation on Foo<T>
((Foo) foo).Value    // calls the implementation on Foo
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...