Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > А как добавить сеттер к свойству?


Автор: Dims 3.11.2008, 23:49
Хочу написать интерфейс public interface INumbersetWritable<T> : INumberset<T> который добавляет к уже существующему в предке свойству сеттер (там был только геттер). 

Было так:

Код

public interface INumberset<T> : IEnumerable<T>
    {
        T this[int i] { get; }


написал так

Код

public interface INumbersetWritable<T> : INumberset<T>, ICloneable
    {
        T this[int i] { set;  }



думал, get уже есть в предке и надо только set добавить, а она ругается, мол, что затеняешь функцию, используй new.

Как правильно написать?

Автор: diadiavova 4.11.2008, 01:14
Код

string tralala
    {
         get
           {
               //Здесь код геттера
            }
          set
            {
               //Здесь код сеттера
             }

     }


в последней версии можно так
Код

string tralala { get; set; }

Автор: Dims 4.11.2008, 04:57
Вопрос был в другом. Если в предке только геттер, то как сделать, чтобы в потомке был и геттер и сеттер.

Я так понял, что это невозможно и что так и было задумано. 

Автор: elbjarn 4.11.2008, 11:59
Цитата(Dims @  4.11.2008,  04:57 Найти цитируемый пост)
Вопрос был в другом. Если в предке только геттер, то как сделать, чтобы в потомке был и геттер и сеттер.

Я так понял, что это невозможно и что так и было задумано.  

это логично - если предок позволяет только считывать значение свойства, было бы весьма странно, если бы потомки позволяли в него и записыватьsmile. работая с полиморфными коллекциями, где элементы производных и базовых классов представлены объектами самого базового класса, как бы можно было определить, допустимо ли присваивание значения его свойству или нет? smile

Автор: diadiavova 4.11.2008, 13:10
Просто свойства рассматривается не как два самостоятельных метода, а как единый член типа. В васике например свойствам вообще добавляются ReadOnly и WrightOnly. Изменение этого положения само собой приведёт к созданию нового свойства. Для того, чтобы свойство можно было переопределить сигнатуры должны совпадать.

Автор: PashaPash 4.11.2008, 14:11
Dims, это глюк наследования интерфейсов. Точнее, не глюк - наследие COM/IDispatch
, в котором были точно такие же ограничения. .NET совместим c COM в обе стороны, могли специально сделать глюк ради священной коровы МС.
Ну есть еще всякие домыслы, типа: "readonly проперти должно быть readonly по своему смыслу и добавление к нему сеттера на самом деле есть затенение первоначального смысла". Или "не изобретай велосипед, возьми стандартные интерфейс ICollection<T> и используй ReadOnlyCollection<T> для non-writable." Но их можно смело игнорировать.

При реализации интерфейса в классе таких ограницений нет.

Автор: Dims 4.11.2008, 18:05
Дело в том, что в Джаве нет языкового понятия свойства, там есть просто договорённость, что если ты называешь методы set-чего-то-там и/или get-чего-то-там, то это сеттер и геттер свойства "чего-то-там".

Естественно, точно так же можно сделать и в Сидиез, то есть, договориться.

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

Про COM понял. Про классы тоже понял.

Автор: kemiisto 4.11.2008, 18:15
Dims, я дико извиняюсь за оффтоп... Почитал Ваши темы и вот что. Название языка, который Вы начали изучать (C#) произносится Си Шарп! И никаких там 
Цитата(Dims @  4.11.2008,  16:05 Найти цитируемый пост)
Сидиез

Цитата
Microsoft C# (pronounced C sharp) is a new programming language designed for building a wide range of enterprise applications that run on the .NET Framework.

Так, просто, на будущее...

Автор: PashaPash 4.11.2008, 19:00
Цитата(Dims @  4.11.2008,  18:05 Найти цитируемый пост)

Естественно, точно так же можно сделать и в Сидиез, то есть, договориться.

Дело в том, что в C# и вообще .net свойство - это не пара функций, которые разработчики договорились называть с set_ и get_. Это одна запись в метаданных и две функции, которые должны следовать определенным правилам (с 24 по 28 в спеке). Поменять половину записи в метаданных довольно проблематично - в случае наследования. А вот создать новую, и привязать к ней методы интерфейса по имени - как в случае реализации интерфейса - вполне можно.
Ну и вообще, в дотнете интерфейсы не наследуются. В дотнете есть понятие Interface type derivation - в твоем случае INumbersetWritable не наследуется от INumberset, он просто требует чтобы класс реализовал еще и INumberset.
Цитата(spec 8.9.11)
To highlight the last difference, consider an interface, IFoo, that has a single method. An interface, IBar, which
derives from it, is requiring that any object type that supports IBar also support IFoo. It does not say anything
about which methods IBar itself will have.

Автор: diadiavova 4.11.2008, 19:56
Вопрос в том, что мешает в базовом классе сделать так
Код

        public virtual string myProp
        {
            get
            {
                return "blablabla";
            }
            set { }

        }

а в производном переопределить свойство?
Код

 public override string myProp
        {
            get
            {
                return base.myProp;
            }
           set
            {
                //код сеттера
            }
        }

Автор: Dims 4.11.2008, 23:28
Цитата(kemiisto @  4.11.2008,  18:15 Найти цитируемый пост)
Так, просто, на будущее... 

В процитированном Вами отрывке написано, в русском переводе, буквально следующее:

"Майкрософтовский C# (читается Си диез) это новый язык программирования, разработанный..."

# это значок диеза, sharp это по английски диез. В этом тексте просто написано, как называется значок # (диез) для тех, кто этого не знает.

Добавлено через 2 минуты и 53 секунды
Цитата(PashaPash @  4.11.2008,  19:00 Найти цитируемый пост)
INumbersetWritable не наследуется от INumberset, он просто требует чтобы класс реализовал еще и INumberset.

А в чём разница кроме терминологии? Интерфейс -- это всё равно нечто предельно абстрактное. Если к старым требованиям добавляются новые, то чем это не наследование?

Добавлено через 4 минуты и 12 секунд
Цитата(diadiavova @  4.11.2008,  19:56 Найти цитируемый пост)
Вопрос в том, что мешает в базовом классе сделать так

Естественно, я примерно так и сделал. Выбросил какое-то исключение. Но это же workaraund. 

Автор: diadiavova 4.11.2008, 23:39
Вот как-то даже сразу не заметил

Цитата(kemiisto @  4.11.2008,  18:15 Найти цитируемый пост)
Any man who is under 30, and is not a liberal, has no heart; and any man who is over 30, and is not a conservative, has no brains. (Winston Churchill)


Зачем же такие крайности то?

И в связи с тем, что ента дело в подпись вынесено - просто интересно: а самому-то сколько(хотябы больше 30 или меньше)?

PS
А замечание то уместное(я о предыдущем сообщении). По аглицки то оно и вправду шарп произносится, странно было бы ожидать, чтобы в английском тексте написали, что произносить надо по-русски.
Другой вопрос: уместно ли вообще переводить название языка программирования. Ну в таком случае зачем ограничиваться только одним словом, когда можно поговорить о чистоте русского языка. smile


Автор: kemiisto 5.11.2008, 00:25
Цитата(Dims @  4.11.2008,  21:28 Найти цитируемый пост)
# это значок диеза, sharp это по английски диез. В этом тексте просто написано, как называется значок # (диез) для тех, кто этого не знает.

Значок # (sharp) и ♯ (диез) вообще говоря различны. В таблице символов Юникод есть специальный символ для диеза «♯» (шестнадцатеричный номер 266F), который отличается от символа октоторпа (решётки) «#». C♯ - до диез (нота), C# - си-шарп (ЯП).
http://ru.wikipedia.org/wiki/CSharp
Цитата

C# (произносится си-шарп)...

Автор: diadiavova 5.11.2008, 00:32
http://www.abbyyonline.ru/translate.aspx?CardId=434;43e;20;434;438;435;437;0;4c;69;6e;67;76;6f;55;6e;69;76;65;72;73;61;6c;20;28;52;75;2d;45;6e;29

Добавлено через 9 минут и 2 секунды
Да, и кстати: в таблице символов внизу пишется название символов. Так вот про символ 266f написано
Цитата

Music Sharp Sign

Автор: diadiavova 5.11.2008, 01:25
Цитата(Dims @  4.11.2008,  23:28 Найти цитируемый пост)
Естественно, я примерно так и сделал. Выбросил какое-то исключение. Но это же workaraund.  

Пардон - сразу не заметил.
Вот, что сделал я :
Код

  public class MyBaseClass
    {
        public virtual string myProp
        {
            get
            {
                return _myProp;
            }
            set { }
        }
        protected string _myProp = "Blablabla";    
    }

    public class MyChildClass:MyBaseClass

    {
        public override string myProp
        {
            get
            {
                return base.myProp;
            }
            set
            {
                base._myProp = value;
            }
        }    
    }


В главной форме разместил кнопку и текстовое поле. Вписал следующий код
Код

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.textBox1.Text = mcc.myProp;
        }
        MyChildClass mcc = new MyChildClass();
         //Обработчик нажатия кнопки
        private void button1_Click(object sender, EventArgs e)
        {
            
            mcc.myProp = "New Value";
            this.textBox1.Text = mcc.myProp;
        }

    
    
    }
  


При запуске в поле было написано Blablalbla. После нажатия кнопки New value.
То есть значение свойству было присвоено, несмотря на то, что в базовом классе сеттер пустой.

Думаю дело не в 
Цитата(Dims @  4.11.2008,  23:28 Найти цитируемый пост)
Но это же workaraund.

А скорее в 
Цитата(Dims @  4.11.2008,  23:28 Найти цитируемый пост)
примерно


Автор: Dims 5.11.2008, 14:33
Цитата(diadiavova @  5.11.2008,  01:25 Найти цитируемый пост)
То есть значение свойству было присвоено, несмотря на то, что в базовом классе сеттер пустой.

Всё правильно, у Вас же mcc имеет тип MyChildClass, а у него сеттер не пустой.

Автор: diadiavova 5.11.2008, 20:30
Ну так ясный перец не пустой. Вопрос был: как добавить сеттер. Это ответ.
Если речь о том, как добавить сеттер к ридонли свойству - тогда ответ один - затенение smile . Создаётся такое же свойство, в геттере возвращается значение одноимённого свойства базового класса, в сеттере - собственная реализация.

Или я чего-то не понял?

Автор: PashaPash 5.11.2008, 20:37
Цитата(Dims @  4.11.2008,  23:28 Найти цитируемый пост)
А в чём разница кроме терминологии? Интерфейс -- это всё равно нечто предельно абстрактное. Если к старым требованиям добавляются новые, то чем это не наследование?

В том и проблема, что не добавляются методы. 
Код

interface A
{
   void MethodA();
}

interface B : A
{
   void MethodB();
}

В интерфейсе A один метод, и в интерфейсе B один метод. И класс может реализовать отдельно A и отдельно B. Скажем, B - implicitly, а А - explicitly:
Код

    class C : B
    {
        public void MethodB()
        {
            throw new NotImplementedException();
        }

        void A.MethodA()
        {
            throw new NotImplementedException();
        }
    }

И тогда у класса C будет public метод MethodB, но не будет метода MethodA. Свойства, которые как бы цельный объект с точки зрения CLR, такого не переживут. Более того, если ты объявляешь свойство с тем же именем в B, то оно не дополнит свойство из A, а просто потребует от С реализовать два свойства с одинаковым именем, о чем тебя и предупреждает компилятор.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)