Възможно ли е да добавите инструмент за достъп към свойство в .NET, като го замените?

Възможно ли е да се направи нещо подобно?

class A
{
    public virtual string prop
    {
        get
        {
            return "A";
        }
    }
}
class B: A
{
    private string X;
    public override string prop
    {
        get
        {
            return X;
        }
        set
        {
            X = value;
        }
    }
}

Тоест базовият клас предоставя виртуално свойство само с GET инструмент за достъп, но дъщерният клас замества GET и също така предоставя SET.

Текущият пример не се компилира, но може би пропускам нещо тук.

Добавено: За пояснение, не, не искам да предефинирам с ново. Искам да добавя нов аксесоар. Знам, че не беше в базовия клас, така че не може да бъде заменен. Добре, нека се опитам да обясня как би изглеждало без синтактичната захар:

class A
{
    public virtual string get_prop()
    {
            return "A";
    }
}
class B: A
{
    private string X;
    public override string get_prop()
    {
        return X;
    }
    public virtual string set_prop()
    {
        X = value;
    }
}

person Vilx-    schedule 13.02.2009    source източник
comment
Отново редакцията - простият отговор е не: не можете.   -  person Marc Gravell    schedule 13.02.2009
comment
Редактирайте това в отговора си и аз ще го приема. :)   -  person Vilx-    schedule 13.02.2009


Отговори (4)


Не, това не е възможно. За съжаление не можете дори да замените и промените нивото на достъп (от protected на public например), както е документирано на MSDN. Бих препоръчал да обмислите леко преструктуриране на кода/класа и да потърсите алтернативен начин за изпълнение на тази задача, като например деклариране на метода за достъп на set с модификатора protected, като използвате метод SetProperty в производния клас.

person Noldorin    schedule 13.02.2009

Не, няма начин да стане това. Помислете как се работи със синтактичната захар на вашата виртуална собственост, т.е. тя се преобразува в:

public virtual string get_prop();

Няма метод set_Prop за замяна и не можете да замените метод, който не съществува.

person ng5000    schedule 13.02.2009
comment
не съм сигурен какво имате предвид, но бихте могли да добавите виртуален метод като свойство „set“, което ще бъде преобразувано във виртуален метод на набор... - person ng5000; 13.02.2009

Можете да скриете внедряването на базовия клас, като използвате ключовата дума 'new' във вашия производен клас. Следното трябва да се компилира успешно:

class A
{
    public virtual string prop
    {
        get
        {
            return "A";
        }
    }
}
class B : A
{
    private string X;
    public new string prop
    {
        get
        {
            return X;
        }
        set
        {
            X = value;
        }
    }
}
person Sam Holloway    schedule 13.02.2009
comment
Въвеждането на различно резервно поле обикновено е рисковано, но... от гледна точка на черната кутия клас А може да има поле и т.н. като основна реализация и всяко използване на това поле би било съмнително... - person Marc Gravell; 13.02.2009

Представянето на ново поле мирише на объркано. И така или иначе трябва да внимавате да не нарушите полиморфизма и наследяването (ами ако базовият клас говори с частното поле?).

По отношение на добавянето на нов достъп при отмяна; простият отговор е „не, не можете“. Когато замените, можете да повлияете само на съществуващите инструменти за достъп, тъй като това е, което е дефинирано във виртуалната таблица за члена (заменен член все още е „притежаван“ от базовия/деклариращ клас, а не от заместващия клас).

Един вариант (не идеален) е да декларирате отново собствеността, но все пак ще ви е необходим начин да говорите с основния клас. Така че, ако инструментът за достъп в базовия клас беше protected:

class A
{
    public string prop
    {
        get;
        protected set;
    }
}
class B : A
{
    public new string prop
    {
        get { return base.prop; }
        set { base.prop = value; }
    }
}
person Marc Gravell    schedule 13.02.2009