Как бы "унаследовать" статические члены?
От: Cynic Россия  
Дата: 16.09.16 08:35
Оценка:
Есть у меня иерархия классов (два уровня), в которой все классы должны иметь статические члены с одинаковыми именами, но разным возвращаемым значением. Вопрос как это сделать? Унаследовать статические члены нельзя (все они будут ссылаться на базовый тип), а copy/paste кода меня как-то не вдохновляет. С другой стороны интерфейсы тут тоже не помогут, т.к. декларировать статические члены не могут. Шаблоны тут то-же не к месту, т.к. не чего передавать в параметра шаблона (<T>). Так что же делать то с этим господа?
Попробую пояснить, что имею ввиду. Шла бы речь о не статических членах я бы сделал так:
class A
{
    protected int field;
    public A()
    {
       field = 1;
    }
    public int Field
    {
        get { return field; }
    }
}

class B : A
{
   public B()
   {
      field = 2;
   }
}
...
var a = new A();
var b = new B();
Console.WriteLine(a.Field);  // 1
Console.WriteLine(b.Field);  // 2

Хотелось бы нечто подобное сделать и со статическими версиями поля field и свойства Field.
:)
Отредактировано 16.09.2016 8:51 Cynic . Предыдущая версия . Еще …
Отредактировано 16.09.2016 8:50 Cynic . Предыдущая версия .
Отредактировано 16.09.2016 8:40 Cynic . Предыдущая версия .
Отредактировано 16.09.2016 8:36 Cynic . Предыдущая версия .
Re: Как бы "унаследовать" статические члены?
От: hardcase Пират http://nemerle.org
Дата: 16.09.16 08:43
Оценка: +2
Здравствуйте, Cynic, Вы писали:

C>Есть у меня иерархия классов (два уровня), в которой все классы должны иметь статические члены с одинаковыми именами, но разным возвращаемым значением. Вопрос как это сделать?


Не делать так. Элементарнейший выход — создание дополнительного абстрактного метода.


abstract class A
{
  public abstract IState GetState();
}


class B : A
{
  private static readonly IState state = new ...;

  public override IState GetState() => state;
}
/* иЗвиНите зА неРовнЫй поЧерК */
Отредактировано 16.09.2016 8:44 hardcase . Предыдущая версия .
Re[2]: Как бы "унаследовать" статические члены?
От: Cynic Россия  
Дата: 16.09.16 08:53
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Не делать так. Элементарнейший выход — создание дополнительного абстрактного метода.


H>
H>abstract class A
H>{
H>  public abstract IState GetState();
H>}


H>class B : A
H>{
H>  private static readonly IState state = new ...;

H>  public override IState GetState() => state;
H>}
H>


Угу, только метод GetState должен быть статическим для обоих классов
:)
Re: Как бы "унаследовать" статические члены?
От: Sinix  
Дата: 16.09.16 08:59
Оценка:
Здравствуйте, Cynic, Вы писали:

C>Есть у меня иерархия классов (два уровня), в которой все классы должны иметь статические члены с одинаковыми именами, но разным возвращаемым значением.


В общем случае так делать низзя, т.к. добавление нового типа-наследника и вэлкам
var derived = Derived.Instance; // oops, Instance property was inherited from Base type.


Мы однажды так _очень_ больно обожглись. В одной из задач надо было к каждому типу прикрутить гуид, ну и сделали static readonly поле TypeId.
Итог был немного предсказуем


Решарпер такие ошибки ловит, но решарпер есть не у всех, а другие инструменты статического анализа используются ещё реже.

Не, есть частные случаи, когда кровь из носу надо иметь одинаковые static-мемберы в разных типах, но для и решения частные, под все сценарии не подходят.
Чтоб не перечислять всё — можно пример, зачем именно оно понадобилось?
Re: Как бы "унаследовать" статические члены?
От: DarthSidius  
Дата: 16.09.16 09:05
Оценка:
Здравствуйте, Cynic, Вы писали:

C>Так что же делать то с этим господа?


Переходить на Nemerle
http://rsdn.org/forum/nemerle/4811692.flat
Автор: artelk
Дата: 09.07.12
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
♠♠♥♠♠♦♥
Re: Как бы "унаследовать" статические члены?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.09.16 09:06
Оценка: 6 (1)
Здравствуйте, Cynic, Вы писали:

В Delphi есть виртуальные статические методы. Это метаклассы. Суть в том, что это синглетоны и они наследуются вместе с классом. Можно сэмулировать такое поведение в C# но вручную.
http://rsdn.org/forum/philosophy/563970.flat
Автор: Serginio1
Дата: 10.03.04
и солнце б утром не вставало, когда бы не было меня
Re[2]: Как бы "унаследовать" статические члены?
От: Cynic Россия  
Дата: 16.09.16 09:12
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Чтоб не перечислять всё — можно пример, зачем именно оно понадобилось?


Ну короче есть у меня базовый абстрактный класс, пусть будет A. От которого наследуют ещё несколько классов, пусть будет В и C. У всех трёх классов должны быть несколько статических свойств, например Type и Name которые должно возвращать разный результат в зависимости от класса для которого вызываются. Надо именно так, т.к. периодически нужно получать значение этих свойств не создавая экземпляр класса, поскольку это не удобно и не нужно.
:)
Re[2]: Как бы "унаследовать" статические члены?
От: Cynic Россия  
Дата: 16.09.16 09:20
Оценка:
Здравствуйте, Serginio1, Вы писали:

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


S>В Delphi есть виртуальные статические методы. Это метаклассы. Суть в том, что это синглетоны и они наследуются вместе с классом. Можно сэмулировать такое поведение в C# но вручную.

S>http://rsdn.org/forum/philosophy/563970.flat
Автор: Serginio1
Дата: 10.03.04


Не понимаю, как меня это избавит от необходимости плодить статические методы с одинаковыми именами в производных классах
:)
Re[3]: Как бы "унаследовать" статические члены?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.09.16 09:27
Оценка:
Здравствуйте, Cynic, Вы писали:

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


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


S>>В Delphi есть виртуальные статические методы. Это метаклассы. Суть в том, что это синглетоны и они наследуются вместе с классом. Можно сэмулировать такое поведение в C# но вручную.

S>>http://rsdn.org/forum/philosophy/563970.flat
Автор: Serginio1
Дата: 10.03.04


C>Не понимаю, как меня это избавит от необходимости плодить статические методы с одинаковыми именами в производных классах


У обычного класса есть статическое поле с типом некого класса который будет сиглетоном и содержать нужные поля. Назовем его метаклассом. Ты будешь плодить только его, а в него прописывать наследника метакласса.
Этот метакласс может переопределть поля, добавлять новые.
и солнце б утром не вставало, когда бы не было меня
Re[4]: Как бы "унаследовать" статические члены?
От: Cynic Россия  
Дата: 16.09.16 09:36
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>У обычного класса есть статическое поле с типом некого класса который будет сиглетоном и содержать нужные поля. Назовем его метаклассом. Ты будешь плодить только его, а в него прописывать наследника метакласса.

S>Этот метакласс может переопределть поля, добавлять новые.

Опять не понимаю. Можно пример.
:)
Re: Как бы "унаследовать" статические члены?
От: Qulac Россия  
Дата: 16.09.16 09:41
Оценка: 6 (1)
Здравствуйте, Cynic, Вы писали:

C>Есть у меня иерархия классов (два уровня), в которой все классы должны иметь статические члены с одинаковыми именами, но разным возвращаемым значением. Вопрос как это сделать? Унаследовать статические члены нельзя (все они будут ссылаться на базовый тип), а copy/paste кода меня как-то не вдохновляет. С другой стороны интерфейсы тут тоже не помогут, т.к. декларировать статические члены не могут. Шаблоны тут то-же не к месту, т.к. не чего передавать в параметра шаблона (<T>). Так что же делать то с этим господа?

C>Попробую пояснить, что имею ввиду. Шла бы речь о не статических членах я бы сделал так:
C>
C>class A
C>{
C>    protected int field;
C>    public A()
C>    {
C>       field = 1;
C>    }
C>    public int Field
C>    {
C>        get { return field; }
C>    }
C>}

C>class B : A
C>{
C>   public B()
C>   {
C>      field = 2;
C>   }
C>}
C>...
C>var a = new A();
C>var b = new B();
C>Console.WriteLine(a.Field);  // 1
C>Console.WriteLine(b.Field);  // 2
C>

C>Хотелось бы нечто подобное сделать и со статическими версиями поля field и свойства Field.

А такой вариант не устроит:
 public class A
    {
        public static object Foo=new object();
    }

    public class B : A
    {
        public static string Foo = "Foo";
    }


Программа – это мысли спрессованные в код
Re[3]: Как бы "унаследовать" статические члены?
От: Sinix  
Дата: 16.09.16 09:42
Оценка: +3
Здравствуйте, Cynic, Вы писали:

C>Ну короче есть у меня базовый абстрактный класс, пусть будет A. ...

А, ну те же грабли, на которые мы наступили. Достаточно добавить наследника и не прописать в нём те же свойства, и использующий код легко может получить значения не для того типа.

Условно рабочих решений тут два:
* Закрытая иерархия типов: кодогенерация (T4) с автозапуском при каждой сборке. + (для большого проекта) тест, который перебирает всех наследников базового типа во всех сборках + проверяет наличие полей.
* Открытая иерархия типов: методы вида XxxHelpers.NameOf<TClass>() (с кэшированием значений в словаре, понятное дело). Плюс всё тот же тест. Как значение вытаскивать — на ваше усмотрение, самый простой способ — через атрибут
Re[2]: Как бы "унаследовать" статические члены?
От: Cynic Россия  
Дата: 16.09.16 09:59
Оценка: -1
Здравствуйте, Qulac, Вы писали:

Q>А такой вариант не устроит:

Q>
Q> public class A
Q>    {
Q>        public static object Foo=new object();
Q>    }

Q>    public class B : A
Q>    {
Q>        public static string Foo = "Foo"; // либо тип перепутали должен быть object, либо нужно дописать new
Q>    }
Q>


И чё это Поле Foo в классах А и В всё равно одно.
:)
Отредактировано 16.09.2016 10:00 Cynic . Предыдущая версия .
Re[3]: Как бы "унаследовать" статические члены?
От: Qulac Россия  
Дата: 16.09.16 10:11
Оценка:
Здравствуйте, Cynic, Вы писали:

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


Q>>А такой вариант не устроит:

Q>>
Q>> public class A
Q>>    {
Q>>        public static object Foo=new object();
Q>>    }

Q>>    public class B : A
Q>>    {
Q>>        public static string Foo = "Foo"; // либо тип перепутали должен быть object, либо нужно дописать new
Q>>    }
Q>>


C>И чё это Поле Foo в классах А и В всё равно одно.


Значения разные, хоть string хоть object, разве не это требуется?
Программа – это мысли спрессованные в код
Re: Как бы "унаследовать" статические члены?
От: hi_octane Беларусь  
Дата: 16.09.16 10:23
Оценка: 1 (1)
C>Хотелось бы нечто подобное сделать и со статическими версиями поля field и свойства Field.
Вот этот
Автор: hi_octane
Дата: 14.02.08
мой изврат 8-летней давности не прокатит?
Re[5]: Как бы "унаследовать" статические члены?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.09.16 10:31
Оценка: 1 (1)
Здравствуйте, Cynic, Вы писали:

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


S>>У обычного класса есть статическое поле с типом некого класса который будет сиглетоном и содержать нужные поля. Назовем его метаклассом. Ты будешь плодить только его, а в него прописывать наследника метакласса.

S>>Этот метакласс может переопределть поля, добавлять новые.

C>Опять не понимаю. Можно пример.


Вот примеры как это организовано в Delphi
http://www.rsdn.org/Forum/Message.aspx?mid=548308&amp;amp;only=1
http://www.rsdn.org/Forum/Message.aspx?mid=558365&amp;amp;only=1
http://www.rsdn.org/Forum/Message.aspx?mid=559531&amp;amp;only=1

Но опять же проблема определения данных классов не определена и доступ к метаклассу из объекта идет через хэш таблицу, а по идее адрес метакласса должен быть прописан в VMT.
typeof и GetType из Net возвращает по сути тот же метакласс, но он вопервых не типизирован и только переопределяет виртуальные методы базового класса Type и нет возможности его расширения.
Для меня лично необходимость метаклассов не оспорима, но интересно как к этому относится программистское сообщество. И может лишний раз заострить внимание на этой проблеме разработчиков компиляторов и сред.
и солнце б утром не вставало, когда бы не было меня
Отредактировано 16.09.2016 10:32 Serginio1 . Предыдущая версия .
Re[3]: Как бы "унаследовать" статические члены?
От: Sharov Россия  
Дата: 16.09.16 10:54
Оценка:
Здравствуйте, Cynic, Вы писали:

C>Ну короче есть у меня базовый абстрактный класс, пусть будет A. От которого наследуют ещё несколько классов, пусть будет В и C. У всех трёх классов должны быть несколько статических свойств, например Type и Name которые должно возвращать разный результат в зависимости от класса для которого вызываются. Надо именно так, т.к. периодически нужно получать значение этих свойств не создавая экземпляр класса, поскольку это не удобно и не нужно.


Не уверен , но атрибуты тут не подойдут?
Кодом людям нужно помогать!
Re[4]: Как бы "унаследовать" статические члены?
От: Cynic Россия  
Дата: 16.09.16 11:10
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Не уверен , но атрибуты тут не подойдут?


Неа.
:)
Re: Как бы "унаследовать" статические члены?
От: kov_serg Россия  
Дата: 16.09.16 11:40
Оценка:
Здравствуйте, Cynic, Вы писали:

C>Есть у меня иерархия классов (два уровня), в которой все классы должны иметь статические члены с одинаковыми именами, но разным возвращаемым значением. Вопрос как это сделать? Унаследовать статические члены нельзя (все они будут ссылаться на базовый тип), а copy/paste кода меня как-то не вдохновляет. С другой стороны интерфейсы тут тоже не помогут, т.к. декларировать статические члены не могут. Шаблоны тут то-же не к месту, т.к. не чего передавать в параметра шаблона (<T>). Так что же делать то с этим господа?

C>Попробую пояснить, что имею ввиду. Шла бы речь о не статических членах я бы сделал так:

C>Хотелось бы нечто подобное сделать и со статическими версиями поля field и свойства Field.


Типа такого ?
public class Props {
    public string name;
}
public class PropsList {
    Dictionary<Type,Props> db = new Dictionary<Type,Props>();
    public PropsList add(Type type,Props props) { 
        db[type] = props; 
        return this; 
    }
    public Props get(Type type) { 
        Props res;
        if (!db.TryGetValue(type,out res))
            throw new NullReferenceException();
        return res;
    }
}
public static class PropsExt {
    static public PropsList traits = new PropsList();
    public static Props static_props(this object a) {
        return a is Type ? traits.get((Type)a) : traits.get(a.GetType());
    }
}
class Example {
    public class A { }
    public class B : A {}
    static Props static_props<T>(T t) { return t is Type ? PropsExt.traits.get(t as Type) : t.static_props(); }
    static void Main(string[] args) {
        PropsExt.traits = new PropsList()
            .add(typeof(A),new Props() { name = "ordinary A" })
            .add(typeof(B),new Props() { name = "The big B" });

        A a = new A(), b = new B();
        
        Console.WriteLine("a.static_props.name={0}",a.static_props().name);
        Console.WriteLine("b.static_props.name={0}",b.static_props().name);

        Console.WriteLine("t(A).name={0}",typeof(A).static_props().name);
        Console.WriteLine("t(B).name={0}",typeof(B).static_props().name);

        Console.WriteLine("static_props(a).name={0}",static_props(a).name);
        Console.WriteLine("static_props(b).name={0}",static_props(b).name);

        Console.WriteLine("static_props(A).name={0}",static_props(typeof(A)).name);
        Console.WriteLine("static_props(B).name={0}",static_props(typeof(B)).name);
    }
}
Re[5]: Как бы "унаследовать" статические члены?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.09.16 14:08
Оценка:
Здравствуйте, Cynic, Вы писали:

S>>Не уверен , но атрибуты тут не подойдут?

C>Неа.

Почему?
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.