А что за проблему ты пыташся решить? Я подобный код писал только в генераторе кода когда часть класса генерировалась автоматом. Но и то сейчас можно пользоваться portial-классами.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Сергей Губанов, Вы писали:
СГ>А что мешает писать так:
Там не всё так просто. класс B в свою осередь реализует другие не мои интерфейсы. Если по-подробнее то так
interface IOwfulInmterface
{
int MethodWithOwfulSignature(owful_parameters)
}
class VeryGoodClass1
{
public:
int MethodWithUnderstandableParameters(understandable_parameters);
}
class VeryGoodClass2
{
public:
int MethodWithUnderstandableParameters(understandable_parameters);
}
class VeryGoodClass3
{
public:
int MethodWithUnderstandableParameters(understandable_parameters);
}
template <typename T>
class Proxy : public T, public IOwfulInterface
{
public:
int MethodWithOwfulSignature(owful_parameters)
{
MethodWithUnderstandableParameters(understandable_parameters);
}
}
и соответсвенно
interface IOwfulInterface
{
int MethodWithOwfulSignature(owful_parameters);
}
interface IVeryGood
{
int MethodWithUnderstandableParameters(understandable_parameters);
}
public class VeryGoodBase : IOwfulInterface
{
public int MethodWithOwfulSignature()
{
((IVeryGood)this).MethodWithUnderstandableParameters(understandable_parameters);
}
}
public class VeryGood1 : VeryGoodBase, IVeryGood
{
public int MethodWithUnderstandableParameters(understandable_parameters);
}
public class VeryGood2 : VeryGoodBase, IVeryGood
{
public int MethodWithUnderstandableParameters(understandable_parameters);
}
public class VeryGood3 : VeryGoodBase, IVeryGood
{
public int MethodWithUnderstandableParameters(understandable_parameters);
}
Внутри Proxy/VeryGoodBase::MethodWithOwfulSignature очень много общей логики.
То что ты написал это тоже хорошо, но интерфесов IVeryGood на самом деле несколько и не все их них всегда реализуются.
К тому же основная проблема для меня в том, что все проверки уходят в run-time и я понятия не имею реализовал ли класс-потомок всё что от него хотел базовый класс пока сам это ручками не проверю или пока не прогоняю тест, а он обширный и это просто неудобно.
Здравствуйте, adontz, Вы писали:
A>То что ты написал это тоже хорошо, но интерфесов IVeryGood на самом деле несколько и не все их них всегда реализуются. A>К тому же основная проблема для меня в том, что все проверки уходят в run-time и я понятия не имею реализовал ли класс-потомок всё что от него хотел базовый класс пока сам это ручками не проверю или пока не прогоняю тест, а он обширный и это просто неудобно.
Я не очень понял — ведь можно же написать несколько абстрактных методов?
Проверять реализацию будет компилятор в compile-time, а не Вы в в run-time.
public abstract class VeryGoodBase:
IOwfulInterface1, IOwfulInterface2, IOwfulInterface3, IOwfulInterface4, IOwfulInterface5,
IVeryGood1, IVeryGood2, IVeryGood3, IVeryGood4, IVeryGood5
{
public abstract int MethodWithUnderstandableParameters1(...1);
public abstract int MethodWithUnderstandableParameters2(...2);
public abstract int MethodWithUnderstandableParameters3(...3);
public abstract int MethodWithUnderstandableParameters4(...4);
public abstract int MethodWithUnderstandableParameters5(...5);
public int MethodWithOwfulSignature1(...1)
{
this.MethodWithUnderstandableParameters1(understandable_parameters1);
}
public int MethodWithOwfulSignature2(...2)
{
this.MethodWithUnderstandableParameters2(understandable_parameters2);
}
public int MethodWithOwfulSignature3(...3)
{
this.MethodWithUnderstandableParameters3(understandable_parameters3);
}
public int MethodWithOwfulSignature4(...4)
{
this.MethodWithUnderstandableParameters4(understandable_parameters4);
}
public int MethodWithOwfulSignature5(...5)
{
this.MethodWithUnderstandableParameters5(understandable_parameters5);
}
}
public abstract class VeryGoodBase:
IOwfulInterface1, IOwfulInterface2, IOwfulInterface3, IOwfulInterface4, IOwfulInterface5,
IVeryGood1, IVeryGood2, IVeryGood3, IVeryGood4, IVeryGood5
{
public abstract int MethodWithUnderstandableParameters1(...1);
public abstract int MethodWithUnderstandableParameters2(...2);
public abstract int MethodWithUnderstandableParameters3(...3);
public abstract int MethodWithUnderstandableParameters4(...4);
public abstract int MethodWithUnderstandableParameters5(...5);
public int MethodWithOwfulSignature1(...1)
{
this.MethodWithUnderstandableParameters1(understandable_parameters1);
}
public int MethodWithOwfulSignature2(...2)
{
this.MethodWithUnderstandableParameters2(understandable_parameters2);
}
public int MethodWithOwfulSignature3(...3)
{
this.MethodWithUnderstandableParameters3(understandable_parameters3);
}
public int MethodWithOwfulSignature4(...4)
{
this.MethodWithUnderstandableParameters4(understandable_parameters4);
}
public int MethodWithOwfulSignature5(...5)
{
this.MethodWithUnderstandableParameters5(understandable_parameters5);
}
}
Проблема в том что иногда я не хочу реализовывать методы MethodWithOwfulSignature4 и MethodWithOwfulSignature5 если то что они делают не поддерживается. Именно НЕ реализовывать, а не заглушки писать. Потому как методов на самом деле огромное количество и писать для 10 объектов которым нужно 3-4 метода по 50 заглушек не охота.
Наследование от параметра шаблона+вызов функции если она есть с Си++ решали эту проблему. А тут я какой-то хернёй маюсь
Здравствуйте, adontz, Вы писали:
A>Проблема в том что иногда я не хочу реализовывать методы MethodWithOwfulSignature4 и MethodWithOwfulSignature5 если то что они делают не поддерживается. Именно НЕ реализовывать, а не заглушки писать. Потому как методов на самом деле огромное количество и писать для 10 объектов которым нужно 3-4 метода по 50 заглушек не охота. A>Наследование от параметра шаблона+вызов функции если она есть с Си++ решали эту проблему. А тут я какой-то хернёй маюсь
А что если все заглушки всего один раз написать?
public abstract class VeryGoodBase: ...
{
public virtual int MethodWithUnderstandableParameters1(...1){заглушка1;}
public virtual int MethodWithUnderstandableParameters2(...2){заглушка2;}
public virtual int MethodWithUnderstandableParameters3(...3){заглушка3;}
public virtual int MethodWithUnderstandableParameters4(...4){заглушка4;}
public virtual int MethodWithUnderstandableParameters5(...5){заглушка5;}
...
public int MethodWithAwfulSignature1(...1)
{
this.MethodWithUnderstandableParameters1(understandable_parameters1);
}
public int MethodWithAwfulSignature2(...2)
{
this.MethodWithUnderstandableParameters2(understandable_parameters2);
}
...
}
А потом, если не хочешь 50 методов переопределять — так и не переопределяй.
Кстати я у себя на прошлой неделе именно так и сделал, вот смотрите:
public abstract class AbstractSpeechStream:
SpeechLib.ISpStreamFormat,
SpeechLib.ISpeechBaseStream,
SpeechLib.ISequentialStream,
SpeechLib.IStream
{
//---SpeechLib.ISpStreamFormat ----------------------------------------------------------------------------------public virtual void GetFormat (ref System.Guid pguidFormatId, System.IntPtr ppCoMemWaveFormatEx) {}
//- SpeechLib.ISpeechBaseStream ----------------------------------------------------------------------------------public virtual int Read (out object buffer, int numberOfBytes) {buffer = null; return 0;}
public virtual object Seek (object position, SpeechLib.SpeechStreamSeekPositionType origin) {return null;}
public virtual int Write (object obj) {return 0;}
public virtual SpeechLib.SpAudioFormat Format{get{return null;} set {}}
//---SpeechLib.ISequentialStream ----------------------------------------------------------------------------------public virtual void RemoteRead (out byte b0, uint requestByteCount, out uint readedByteCount) {b0 = 0; readedByteCount = 0;}
public virtual void RemoteWrite (ref byte b0, uint requestByteCount, out uint writtenByteCount) {writtenByteCount = 0;}
//---SpeechLib.IStream---------------------------------------------------------------------------------------------public virtual void RemoteSeek (SpeechLib._LARGE_INTEGER dlibMove, uint dwOrigin, out SpeechLib._ULARGE_INTEGER plibNewPosition) {plibNewPosition.QuadPart = (ulong)dlibMove.QuadPart;}
public virtual void Clone (out SpeechLib.IStream newStream) {newStream = null;}
public virtual void Commit (uint grfCommitFlags) {}
public virtual void RemoteCopyTo (SpeechLib.IStream pstm, SpeechLib._ULARGE_INTEGER cb, out SpeechLib._ULARGE_INTEGER pcbRead, out SpeechLib._ULARGE_INTEGER pcbWritten) {pcbRead = new SpeechLib._ULARGE_INTEGER(); pcbWritten = new SpeechLib._ULARGE_INTEGER();}
public virtual void Revert () {}
public virtual void SetSize (SpeechLib._ULARGE_INTEGER libNewSize) {}
public virtual void Stat (out SpeechLib.tagSTATSTG statstg, uint grfStatFlag) {statstg = new SpeechLib.tagSTATSTG();}
public virtual void LockRegion (SpeechLib._ULARGE_INTEGER libOffset, SpeechLib._ULARGE_INTEGER cb, uint dwLockType) {}
public virtual void UnlockRegion (SpeechLib._ULARGE_INTEGER libOffset, SpeechLib._ULARGE_INTEGER cb, uint dwLockType){}
}
А потом отнаследовался от AbstractSpeechStream в AudioInput и в AudioOutput
в которых переопределил только RemoteSeek, GetFormat
и соответственно RemoteRead либо RemoteWrite.
На переопределение остальных методов забил. Вот и все дела...
Здравствуйте, VladD2, Вы писали:
A>>А конкретно с методами GetGuidProperty SetGuidProperty GetProperty SetProperty интерфейса IVsHierarchy VD>Это же КОМ. Причем тут дженерики и наследование?
adontz,
ПК>> А почему бы не попробовать C++/CLI? В нем есть полноценные шаблоны ПК>> C++.
a> Ну и где скачать его компилятор? Только чтоб не beta unstable a> prerelease candidate preview.
Мне показалось, что ты generics использовал из C# 2.0, который в том же
статусе, что и C++/CLI?
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Мне показалось, что ты generics использовал из C# 2.0, который в том же статусе, что и C++/CLI?
Нет Я сказал, что мне нехватает шаблонов от параметров которых можно наследоваться. Разве от параметров дженериков можно наследоваться? АФАИК нет. Так что дженерики идут лесом.
Я на 2003-й студии. Framework 1.1
Я собственно не столько решение ищу, сколько поплакаться захотел
Здравствуйте, adontz, Вы писали:
A>>>Воюю с MS'ными интерфейсами. Меняю страшную иерархию на не очень страшную. VD>>А конкретно?
A>А конкретно с методами GetGuidProperty SetGuidProperty GetProperty SetProperty интерфейса IVsHierarchy
И зачем тебе понадобилось наследование от параметра шаблона?
Здравствуйте, AndrewVK, Вы писали:
A>>А конкретно с методами GetGuidProperty SetGuidProperty GetProperty SetProperty интерфейса IVsHierarchy AVK>И зачем тебе понадобилось наследование от параметра шаблона?
Ну как. Шаблонный класс реализует IVsUIHierarchy и перенаправляет подкорректированные вызовы параметру шаблона (который по ходу базовый класс).
Да, это в принципе можно заменить вызовом виртуального метода, но идеологически это не правильно. Виртуальное наследование подразумевает множество наследований неизвестно кем, а тут параметр шаблона выступает не в качестве расширителя, а в качестве политики поведения.
То есть я не расширяю базовую реализацию IVsUIHierarchy несколькими способами, я создаю её с разными политиками поведения.
То что я написал именно так как я написал, а не использовал казалось бы более очевидные виртуальные методы, результат того что я пытался выразить своё видение архитектуры и показывает что в данном конкретном случае моё видение архитектуры классов языком не выражалось. Холивар по поводу "Вот в .Net нормальных шаблонов нету, вай-вай-вай!" я не разводить не собираюсь, просто было интересно насколько часто другие попадали в такую же ситуацию.
Ну и производительность конечно вообще говоря разная получается, хотя вызов виртуального метода это не катастрофа, но зато потенциал оптимизации гораздо выше. Но в контексте текущей задачи это меня вообще не беспокоит — студия сама по себе довольно тормозная штука.
Здравствуйте, adontz, Вы писали:
A>Ну как. Шаблонный класс реализует IVsUIHierarchy и перенаправляет подкорректированные вызовы параметру шаблона (который по ходу базовый класс).
Вот и интересно, что это за подкорректированные вызовы. Что там корректировать?
A>То есть я не расширяю базовую реализацию IVsUIHierarchy несколькими способами, я создаю её с разными политиками поведения.
Т.е. тебе фактически нужны миксины. Ну так с этого и надо было начинать. Реализация миксинов на базе плюсовых шаблонов тоже далека от идеала. И, да, миксинов в C# не хватает.
A>Ну и производительность конечно вообще говоря разная получается, хотя вызов виртуального метода это не катастрофа, но зато потенциал оптимизации гораздо выше.
Замедление виртуальных методов на фоне интеропа с СОМом? Не смешите мои тапочки.
Здравствуйте, AndrewVK, Вы писали:
A>>Ну как. Шаблонный класс реализует IVsUIHierarchy и перенаправляет подкорректированные вызовы параметру шаблона (который по ходу базовый класс). AVK>Вот и интересно, что это за подкорректированные вызовы. Что там корректировать?
Например есть 4 своства ассоциированных с именем: VSHPROPID_SaveName, VSHPROPID_Caption, VSHPROPID_Name, VSHPROPID_EditLabel. В моём случае они все обозначают одно и то же. Мне надо обращения к ним перенаправлять на одно и тоже свойство.
A>>То есть я не расширяю базовую реализацию IVsUIHierarchy несколькими способами, я создаю её с разными политиками поведения. AVK>Т.е. тебе фактически нужны миксины. Ну так с этого и надо было начинать. Реализация миксинов на базе плюсовых шаблонов тоже далека от идеала. И, да, миксинов в C# не хватает.
Ну можно и миксинами назвать, хотя термин policy мне как-то ближе.
A>>Ну и производительность конечно вообще говоря разная получается, хотя вызов виртуального метода это не катастрофа, но зато потенциал оптимизации гораздо выше. AVK>Замедление виртуальных методов на фоне интеропа с СОМом? Не смешите мои тапочки.
Нет, я вообще. Говорю же, что в контексте текущей задачи меня не это волнует, но вообще говоря это тоже имеетм есто быть.