C# properties
От: Аноним  
Дата: 27.08.10 07:47
Оценка: :)
Привет!

Волнует следующий вопрос:


class A
{
   protected int _p;
   public int P
   {
      get
      {
         return 1;
      }
   }
}

class B : A
{
   public int P
   {
      set
      {
         _p = value;
      }
   }
}

class Program
{
   static void Main(string[] cmd)
   {
       B b = new B();
       int i = b.P; // A.P (get)
       b.P = 3;     // B.P (set)
   }
}

Можно ли как то добиться такого? Понятно, что в B можно сделать new public int P { get { return base.P; } } ... А как то по проще?

Спасибо!
Re: C# properties
От: QrystaL Украина  
Дата: 27.08.10 08:08
Оценка:
    class A
    {
        protected int _p;
        public virtual int P
        {
            get
            {
                return 1;
            }
            set { }
        }
    }

    class B : A
    {
        public override int P
        {
            set
            {
                _p = value;
            }
        }
    }
Re[2]: C# properties
От: Аноним  
Дата: 27.08.10 08:15
Оценка:
Здравствуйте, QrystaL, Вы писали:

QL>
QL>    class A
QL>    {
QL>        protected int _p;
QL>        public virtual int P
QL>        {
QL>            get
QL>            {
QL>                return 1;
QL>            }
QL>            set { }
QL>        }
QL>    }

QL>    class B : A
QL>    {
QL>        public override int P
QL>        {
QL>            set
QL>            {
QL>                _p = value;
QL>            }
QL>        }
QL>    }
QL>


Спасибо, но хотелось бы еще что-бы компилятор не давал менять A.P т.е:
...
A a = new A();
a.P = 5; // Compiler error
Re[3]: C# properties
От: QrystaL Украина  
Дата: 27.08.10 08:24
Оценка:
А>A a = new A();
А>a.P = 5; // Compiler error


Так не получится. Как вариант, можно написать


    class A
    {
        protected int _p;
        public virtual int P
        {
            get { return 1; }
            set { throw new NotSupportedException(); }
        }
    }
Re[4]: C# properties
От: Аноним  
Дата: 27.08.10 08:26
Оценка:
Здравствуйте, QrystaL, Вы писали:

А>>A a = new A();

А>>a.P = 5; // Compiler error


QL>Так не получится. Как вариант, можно написать



QL>
QL>    class A
QL>    {
QL>        protected int _p;
QL>        public virtual int P
QL>        {
QL>            get { return 1; }
QL>            set { throw new NotSupportedException(); }
QL>        }
QL>    }
QL>


Да знаю Ну ладно все равно спасибо
Re: C# properties
От: Sinix  
Дата: 27.08.10 08:55
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Привет!


class B : A
{
   public new int P
   {
      get
      {
         return _p;
      }
      set
      {
         _p = value;
      }
   }
}


Когда коллеги станут вас убивать, меня не выдавайте, ок?
Re[2]: C# properties
От: Аноним  
Дата: 27.08.10 08:59
Оценка: :)
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Аноним, Вы писали:


А>>Привет!


S>
S>class B : A
S>{
S>   public new int P
S>   {
S>      get
S>      {
S>         return _p;
S>      }
S>      set
S>      {
S>         _p = value;
S>      }
S>   }
S>}
S>


S>Когда коллеги станут вас убивать, меня не выдавайте, ок?

Уаааууу... Как вы догадались?
Re[2]: C# properties
От: QrystaL Украина  
Дата: 27.08.10 09:07
Оценка: :)
S>Когда коллеги станут вас убивать, меня не выдавайте, ок?
Насколько я понял, автор изначально от этого способа отказался: "Понятно, что в B можно сделать new public int P { get { return base.P; } } ... А как то по проще?"
Хотя не совсем понятно, какую задачу он вообще решает
Re[3]: C# properties
От: Аноним  
Дата: 27.08.10 09:17
Оценка:
Здравствуйте, QrystaL, Вы писали:

S>>Когда коллеги станут вас убивать, меня не выдавайте, ок?

QL>Насколько я понял, автор изначально от этого способа отказался: "Понятно, что в B можно сделать new public int P { get { return base.P; } } ... А как то по проще?"
QL>Хотя не совсем понятно, какую задачу он вообще решает
Именно!

Задача можно кратко объяснить так: Класс A — Read-Only, a B — Read-Write. Не хочется дублировать код, поэтому последний наследуется от первого.
Re[3]: C# properties
От: Sinix  
Дата: 27.08.10 09:46
Оценка:
Здравствуйте, QrystaL, Вы писали:

QL>Насколько я понял, автор изначально от этого способа отказался: "Понятно, что в B можно сделать new public int P { get { return base.P; } } ... А как то по проще?"


Туплю Медицинский факт: Excel VBA разрушает мозг.
Re[4]: C# properties
От: _FRED_ Черногория
Дата: 27.08.10 09:48
Оценка: :)
Здравствуйте, Аноним, Вы писали:

А>Не хочется дублировать код, поэтому последний наследуется от первого.


Где, интересно, только учат такому способу устранения дублирования кода
Help will always be given at Hogwarts to those who ask for it.
Re: C# properties
От: Uzzy Россия  
Дата: 29.08.10 07:10
Оценка:
Здравствуйте, Аноним, Вы писали:

Меняйте дизайн, не там решаете проблему.
Re[2]: C# properties
От: Аноним  
Дата: 29.08.10 11:10
Оценка:
Здравствуйте, Uzzy, Вы писали:

U>Здравствуйте, Аноним, Вы писали:


U>Меняйте дизайн, не там решаете проблему.


Хмм... Ок, что Вы посоветуете?

Опишу задачу по подробнее:

Есть класс, например User.

Есть два типа потребителей этого класса — одним можно только читать, другим читать и менять.

Соответсвенно, пишется два класса — UserBaseRO, со свойствами только get, и наследник User : UserBaseRO со свойствами get и set.
Логика в get идеентична в обоих классах. Очень хочется иметь защиту от изменения свойств UserBaseRO на уровне компилятора.

Как можно это реализовать правильно\хорошо\красиво?

Спасибо
Re[3]: C# properties
От: Uzzy Россия  
Дата: 30.08.10 06:14
Оценка: +1
Здравствуйте, Аноним, Вы писали:

Например, так:
public abstract class Base
{
    private int p;

    protected int GetP() 
    {
        return p;
    }

    protected void SetP(int value)
    {
        p = value;
    }
}

public class User : Base
{
    public int P
    {
        get { return GetP(); }
        set { SetP(value); }
    }
}

public class ReadOnlyUser : Base
{
    public int P
    {
        get { return GetP(); }
    }
}
Re[4]: C# properties
От: _FRED_ Черногория
Дата: 30.08.10 06:34
Оценка: 1 (1) +1
Здравствуйте, Uzzy, Вы писали:

U>Например, так:


U>public abstract class Base
U>{
U>    private int p;

U>    protected int GetP() 
U>    {
U>        return p;
U>    }

U>    protected void SetP(int value)
U>    {
U>        p = value;
U>    }
U>}


Категорически согласен, только вот нужны методы и почему бы не обойтись защищённым свойством?

U>public abstract class Base
U>{
U>    protected int PropertyCore { get; set; };
U>}
Help will always be given at Hogwarts to those who ask for it.
Re[5]: C# properties
От: Uzzy Россия  
Дата: 30.08.10 06:36
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Категорически согласен, только вот нужны методы и почему бы не обойтись защищённым свойством?


можно и свойство, тут уже не принципиально
Re[3]: C# properties
От: _FRED_ Черногория
Дата: 30.08.10 06:39
Оценка: +1
Здравствуйте, Аноним, Вы писали:

U>>Меняйте дизайн, не там решаете проблему.


А>Хмм... Ок, что Вы посоветуете?

А>Опишу задачу по подробнее:
А>Есть класс, например User.
А>Есть два типа потребителей этого класса — одним можно только читать, другим читать и менять.

Речь идёт обо всех свойствах? Подойдёт ли такой вариант:

interface IUser
{
  int Property1 { get; }
  string Property2 { get; }
}

classs User : IUser
{
  public int Property1 { get; set; }
  public string Property2 { get; set; }
}


Соответственно, тем, кто может только читать, отдаётся интерфейс, остальные могут использовать класс. Если всем нужны непременно экземпляры классов и свойств [относительно] много, ИМХО, более правильным решением было бы написание одного класса с get и set, флагом ReadOnly и бросанием InvalidOperationException из сеттеров ридонли-объекта. Так, например, спроектированны классы в System.Globalization Namespace.
Help will always be given at Hogwarts to those who ask for it.
Re[4]: C# properties
От: Uzzy Россия  
Дата: 30.08.10 06:48
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Соответственно, тем, кто может только читать, отдаётся интерфейс, остальные могут использовать класс.

Лазейка для изменения свойства останется

IUser iUser = new User();

((iUser)user).Property1 = 1;

Если имеется попытка закрыть возможность изменения значения свойства на этапе компиляции, то в рантайме и подавно такую возможность давать нельзя
Re[5]: C# properties
От: _FRED_ Черногория
Дата: 30.08.10 07:05
Оценка:
Здравствуйте, Uzzy, Вы писали:

_FR>>Соответственно, тем, кто может только читать, отдаётся интерфейс, остальные могут использовать класс.

U>Лазейка для изменения свойства останется

Она имеется всегда
Help will always be given at Hogwarts to those who ask for it.
Re[6]: C# properties
От: Jolly Roger  
Дата: 30.08.10 09:17
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, Uzzy, Вы писали:


_FR>>>Соответственно, тем, кто может только читать, отдаётся интерфейс, остальные могут использовать класс.

U>>Лазейка для изменения свойства останется

_FR>Она имеется всегда


Ну можно вынести интерфейсы доступа в прокси-объекты и отдавать их. Но вот надо ли всё это, я лично сомневаюсь.
"Нормальные герои всегда идут в обход!"
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.