Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Можно определить прописан ли виртуальный метод в дочернем классе? / 25 сообщений из 50, страница 1 из 2
20.01.2017, 15:35
    #39388538
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Есть такой код
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
namespace Test {
	class A {
		public A() {
			Init();
		}

		void Init() {
			if(тут как-то проверить) {
				Console.WriteLine("Method() прописан");
			} else {
				Console.WriteLine("Method() не прописан");
			}
		}

		public virtual void Method() {
			Console.WriteLine("A.Method()");
		}
	}

	class B:A {
		public override void Method() {
			Console.WriteLine("B.Method()");
		}
	}

	class C:A {
	}

	static class Test1 {
		static void Main(string[] args) {
			var b = new B();
			b.Method();
			var c = new C();
			c.Method();
		}
	}
}


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

Как-то можно в базовом это определить?
Неважно во время компиляции или во время выполнения. Суть в том базовый класс используется во многих проектах и сейчас просто приходится выставлять флаг что он прописан. Хочется избавиться от флага.
...
Рейтинг: 0 / 0
20.01.2017, 16:08
    #39388565
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Dima T, интернеты говорят можно так попробовать...
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
public static class Helper
{
	public static bool IsOver<T>(this T v, string method) where T: class
	{
		return v.GetType().GetMethod(method).DeclaringType != typeof(T);
	}
......................
		void Init() {
			if(this.IsOver("Method")) {
				Console.WriteLine("Method() прописан");
			} else {
				Console.WriteLine("Method() не прописан");
			}
		}
}
...
Рейтинг: 0 / 0
20.01.2017, 16:25
    #39388577
winsky!
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
наверное можно как-то так, но имхо это изврат какой-то.
базовый класс не должен знать про своих наследников ничего
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
 
class A
    {
        public virtual void X()
        {
            if (this.GetType() == typeof(A))
            {
                Console.WriteLine("Not ovverided");
            }
        }
    }

    class B : A
    {
        public override void X()
        {
            base.X();
            Console.WriteLine("overrided");
        }
    }
...
Рейтинг: 0 / 0
20.01.2017, 16:32
    #39388581
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Мне не показалось что виртуальный метод из конструктора зовётся?
...
Рейтинг: 0 / 0
20.01.2017, 16:39
    #39388586
winsky!
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Изопропил,

где?
...
Рейтинг: 0 / 0
20.01.2017, 17:10
    #39388602
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
buser, спасибо, работает.
Исходник
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
namespace Test {
	public static class Helper {
		public static bool IsOver<T>(this T v, string method) where T: class
		{
			return v.GetType().GetMethod(method).DeclaringType != typeof(T);
		}
	}

	class A {
		public A() {
			Init();
		}

		void Init() {
			if(this.IsOver("Method")) {
				Console.WriteLine("Method() прописан");
			} else {
				Console.WriteLine("Method() не прописан");
			}
		}

		public virtual void Method() {
			Console.WriteLine("A.Method()");
		}
	}

	class B:A {
		public override void Method() {
			Console.WriteLine("B.Method()");
		}
	}

	class C:A {
	}

	static class Test1 {
		static void Main(string[] args) {
			var b = new B();
			b.Method();
			var c = new C();
			c.Method();
		}
	}
}


winsky!наверное можно как-то так, но имхо это изврат какой-то.
базовый класс не должен знать про своих наследников ничего
Изврат, но так удобнее чем кучу классов городить. Базовый готовит несколько типов данных и вызывает методы дочерних для обработки. Если какой-то метод не прописан, то значит в данном случае оно не надо и подготовку можно не делать.

Проверять прописан ли метод запуском самого метода не вариант, т.к. сначала надо данные для его вызова приготовить, а после уже поздно проверять.
...
Рейтинг: 0 / 0
20.01.2017, 17:46
    #39388628
refreg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Dima T,

А использовать интерфейс для этой цели?
Типа такого
...
Рейтинг: 0 / 0
20.01.2017, 18:02
    #39388635
Addx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Dima T,
я обычно интерфейсы для этого к классам добавляю, методы все же обычно не просто так к классу привязаны.
Типа метод есть - так почему бы его не вызвать? )))
Ввести интерфейс IMyMethodSupportable, а сам метод сделать приватным - его даже вызвать не получится.
...
Рейтинг: 0 / 0
20.01.2017, 20:55
    #39388718
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
ООП и реальность иногда расходятся. У меня задача закодить пару сотен проектов с минимумом напряга. Проект это написать 1-2 виртуальных метода.
...
Рейтинг: 0 / 0
21.01.2017, 00:42
    #39388802
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Dima T,

Тогда сделай без напряга метод virtual bool IsMethodAOverloaded() {return false;}
И вместе с методом A переопределяй его тоже. Просто, надёжно, быстро и компактно. Твой метод с рефлекшн это вычурно overingenering.
...
Рейтинг: 0 / 0
21.01.2017, 13:37
    #39388891
refreg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
mikronDima T,

Тогда сделай без напряга метод virtual bool IsMethodAOverloaded() {return false;}
И вместе с методом A переопределяй его тоже. Просто, надёжно, быстро и компактно. Твой метод с рефлекшн это вычурно overingenering.
Dima Tсейчас просто приходится выставлять флаг что он прописан. Хочется избавиться от флага.Круг замкнулся
...
Рейтинг: 0 / 0
21.01.2017, 16:04
    #39388919
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
mikronDima T,

Тогда сделай без напряга метод virtual bool IsMethodAOverloaded() {return false;}
И вместе с методом A переопределяй его тоже. Просто, надёжно, быстро и компактно. Твой метод с рефлекшн это вычурно overingenering.
Какая разница: метод сделать или флаг, все равно писать это надо. А тут на автомате все само работает.

Можно по фэншую через делегаты (Action) сделать, но так тоже букав больше.
...
Рейтинг: 0 / 0
23.01.2017, 14:50
    #39389528
LameUser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Dima T
Есть такой код
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
namespace Test {
	class A {
		public A() {
			Init();
		}

		void Init() {
			if(тут как-то проверить) {
				Console.WriteLine("Method() прописан");
			} else {
				Console.WriteLine("Method() не прописан");
			}
		}

		public virtual void Method() {
			Console.WriteLine("A.Method()");
		}
	}

	class B:A {
		public override void Method() {
			Console.WriteLine("B.Method()");
		}
	}

	class C:A {
	}

	static class Test1 {
		static void Main(string[] args) {
			var b = new B();
			b.Method();
			var c = new C();
			c.Method();
		}
	}
}


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

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

Ответ кроется в самом вопросе. Нужно вынести вызов методов базового класса в переписанные методы дочернего класса (равносильно затратам на убирание флагов).

Например:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
    class Class1
    {

        protected virtual void DoSomeShit()
        {
            DoBaseShit();
        }

        private void DoBaseShit()
        {
        }

        protected void DoAdditionalShit()
        {
        }
    }

    class Class2 : Class1
    {
        protected override void DoSomeShit()
        {
            // if it is Necessary, depends on the architecture
            base.DoSomeShit();
            DoAdditionalShit();
        }
    }
...
Рейтинг: 0 / 0
23.01.2017, 14:55
    #39389532
LameUser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Ну и чтобы в связанных проектах ничего не поломалось - текущий флаг пометьте Obsolete с ошибкой компиляции, чтобы при следующей перекомпиляции связанных проектов не забыли об этом.
...
Рейтинг: 0 / 0
23.01.2017, 15:36
    #39389578
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
LameUser, ты красным суть выделил, но похоже ее не понял. Мне надо ДО вызова метода знать что он не прописан.
Базовый класс выглядел так (схематично)
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
class Base {
   void Поработать() {
      try {
         инфа = Скачать();
         результат = Распарсить(инфа);
         Сохранить(результат);
     } catch {
         ЗаписьВЛог("Не сохранилось");
     }
   }

   virtual Сохранить(результат) {
        throw new Exception("Пропиши Сохранить() в дочернем классе");
   }
}


Т.е. сначала все качалось и парсилось чтобы в итоге выяснить что сохранять нечем.

Сейчас стало так
Код: c#
1.
2.
3.
4.
5.
6.
   void Поработать() {
       if(!ЕстьМетод("Сохранить")) {
            ЗаписьВЛог("Пропиши Сохранить() в дочернем классе");
            return;
       }
     ...


Т.е. не прописан метод, значит не качаем и не парсим.
...
Рейтинг: 0 / 0
23.01.2017, 17:17
    #39389688
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Dima T,

Течнически проблема решена, и если тя всё устраивает то тема закрыта.
ИМЧО Архитектура кривая. Опиши поведение метода "поработать" в документации к нему и я думаю станет очевидно что сним не так: его поведение больше не опредлеяется состоянием обьекта. Помимо того что это не очевидно:
Представь ситуацию где

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
class Intermediate : Base 
{
   override Сохранить(результат) 
   {
   // Provide common implementation for save results into Database
   }
   protected visrtual void SaveHeader() { throw new NotImplementedException(); }
   protected visrtual void SaveReportRow() { throw new NotImplementedException(); }
   protected visrtual void SaveFooter() { throw new NotImplementedException(); }
}

class Derived1 : Intermediate 
{
   // ....
}

class Derived2 : Intermediate 
{
    // ...
}


Уже не работает по причине что для Intermediate идее автора не должен работать "Поработат".
Практически ты требуеш следующий увовень наследования должен быть последним и завершённым.

Может тебе просто надо обявить "Сохранить" абстрактным?
...
Рейтинг: 0 / 0
23.01.2017, 19:24
    #39389799
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Dima TООП и реальность иногда расходятся. У меня задача закодить пару сотен проектов с минимумом напряга. Проект это написать 1-2 виртуальных метода.

Это не ООП и реальность расходятся, это некорректные ожидания не сходятся с реальностью. Тут требуется декомпозиция класса. Возможно всё можно свести к красивой реализации на Visitor.

Суть правильно спроектированого класса по канонам ООП это как раз не знать в базовом классе, переопределён метод или нет. Иначе будет нарушен принцип Лисков. А если это по каким-то причинам потребовалось, тебе приходится тулить какие-то флаги, значит ты совершенно, абсолютно точно что-то делаешь неправильно, и костыли вряд ли помогут на перспективу.
...
Рейтинг: 0 / 0
23.01.2017, 19:25
    #39389802
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Dima TТ.е. не прописан метод, значит не качаем и не парсим.

Почему бы не делегировать принятие этого решения? В общем, до самой жути, как криво.
...
Рейтинг: 0 / 0
23.01.2017, 20:00
    #39389828
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
hVosttСуть правильно спроектированого класса по канонам ООП это ...
... это соответствие канонам ООП. На ООП жизнь не заканчивается, я уже написал.

Есть конечная задача, еще раз конечная , и мне не надо ее раздувать до вселенской масштабируемости, максимальной повторной используемости кода и т.д. в соответствии с канонами ООП. Мне надо ее решить минимальным количеством букав в дочерних классах, чтобы максимально облегчить жизнь тому кто будет эти 2-3 метода прописывать сотню раз.

PS Задача уже успешно решена похожим образом на другом ЯП, сейчас просто переходим на C#. Мне не надо запаса прочности типа "завтра что-то потребуется а оно не впишется в твою архитектуру", соблюдение теории именно этот запас прочности создает. Что-то усложнять только ради соблюдения теории просто не надо.
...
Рейтинг: 0 / 0
23.01.2017, 20:12
    #39389834
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
mikronТечнически проблема решена, и если тя всё устраивает то тема закрыта.
Технически решена, но вдруг я что-то не знаю и мне дадут лучшее решение. Бывает и такое, я себя самым умным не считаю, поэтому тему не надо закрывать.
...
Рейтинг: 0 / 0
24.01.2017, 10:55
    #39390103
LameUser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Dima TLameUser, ты красным суть выделил, но похоже ее не понял. Мне надо ДО вызова метода знать что он не прописан.
Базовый класс выглядел так (схематично)
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
class Base {
   void Поработать() {
      try {
         инфа = Скачать();
         результат = Распарсить(инфа);
         Сохранить(результат);
     } catch {
         ЗаписьВЛог("Не сохранилось");
     }
   }

   virtual Сохранить(результат) {
        throw new Exception("Пропиши Сохранить() в дочернем классе");
   }
}




Т.е. сначала все качалось и парсилось чтобы в итоге выяснить что сохранять нечем.

Сейчас стало так
Код: c#
1.
2.
3.
4.
5.
6.
   void Поработать() {
       if(!ЕстьМетод("Сохранить")) {
            ЗаписьВЛог("Пропиши Сохранить() в дочернем классе");
            return;
       }
     ...


Т.е. не прописан метод, значит не качаем и не парсим.

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

Но так как тебе не нужно правильное решение, а быстрое - вопрос снимается. Либо ты возможно не видишь как можно применить мое предложенное решение (принцип простой - если что-то не должно запускаться, надо не костыли делать, а просто не запускать).
...
Рейтинг: 0 / 0
24.01.2017, 18:26
    #39390551
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Dima TЕсть конечная задача, еще раз конечная

Судя по твоей же задаче, переопределение метода Сохранить вовсе не означает, что непосредственно сохранение реализовано. Кроме того, как это тестировать? В общем, "решение" своей задачи ты и сам прекрасно знал ещё до того, как создал тему. Определить, что метод переопределён в дочернем классе, задачка вполне себе студенческая.

Но утверждения типа "ООП и реальность не сходится", это попытка оправдать неудачу при попытке забить гвоздь кулаком. Вот с этим не согласен.
...
Рейтинг: 0 / 0
24.01.2017, 18:58
    #39390591
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
hVostt В общем, "решение" своей задачи ты и сам прекрасно знал ещё до того, как создал тему.
У тебя хрустальный шар запылился, протри, я не студент, C#/.Net по немногу изучаю (это вторая серьезная поделка), в книгах внимание заостряю на том что мне реально нужно, знаю что есть рефлексия, но мне не до нее, просто пролистал эту тему в книгах. Интуитивно было понятно что она может помочь в данном случае - вот и спросил и ответили.
То что рефлексией пользуются все сереализаторы это фэншуй?

hVosttНо утверждения типа "ООП и реальность не сходится", это попытка оправдать неудачу при попытке забить гвоздь кулаком. Вот с этим не согласен.
Как бы все хорошо, просто хотел еще лучше сделать. Вместо того чтобы выдавать исключение что метод не прописан - хочу проверять заранее. ХЗ чего вы все тут меня жизни учить собрались. Не мальчик уже.

Формально ООП нарушаю, хотя тоже спорный вопрос. Если тоже самое сделаю через делегаты или интерфейсы и буду в базовом классе проверять предоставлен ли делегат/интерфейс, то будет фэншуй, ничего не изменится, но в дочернем классе будет больше букав.
...
Рейтинг: 0 / 0
24.01.2017, 19:23
    #39390602
refreg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Dima TФормально ООП нарушаю, хотя тоже спорный вопросТы нарушаешь, как минимум 4 принципа из SOLID. Принцип D под вопросом, хотя, уверен ты его тоже нарушаешь. И это в трех классах.

Dima TЕсли тоже самое сделаю через делегаты или интерфейсы и буду в базовом классе проверять предоставлен ли делегат/интерфейс, то будет фэншуй, ничего не изменится , но в дочернем классе будет больше букав.Да, ничего не изменится, ты так же будешь нарушать эти принципы. Ну, может, если повезет, ты начнешь соблюдать какой-либо принцип.

Так что забей
...
Рейтинг: 0 / 0
24.01.2017, 19:38
    #39390611
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно определить прописан ли виртуальный метод в дочернем классе?
Похоже тему пора закрывать, полноценное ТЗ я не готов выложить, а домыслов у каждого немеряно.
Шары хрустальные протрите, прежде чем телепатию включать
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Можно определить прописан ли виртуальный метод в дочернем классе? / 25 сообщений из 50, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]