Я бы наследовал, чтобы конкретный объект был динамическим и задавался с помощью дополнительной настройки некоторого типа, такого как файл app.config.
Вот пример:
//PROGRAM A
public class MySuperClass : OldIneritanceObjectVersion
{
........Stuff Goes Here
}
//PROGRAM B
public class MySuperClass : OldIneritanceObjectVersion
{
........Stuff Goes Here
}
//PROGRAM B .....a Few Years Later.....
public class MySuperClass : NewIneritanceObjectVersion
{
........Stuff Goes Here
}
Как вы можете догадаться, я хочу, чтобы мои старые вещи продолжали использовать OldIneritanceObjectVersion, в то время как я хочу создавать новые вещи, а также обновлять старые вещи, чтобы использовать более обновленную версию NewIneritanceObjectVersion. Есть ли способ сделать это динамически?
Нет. С# статически типизирован. Иерархия типов для каждого класса должна быть известна во время компиляции.
Вы можете сделать это через T4. Вы сможете настроить шаблон для своего класса и легко изменить это поведение.
Это становится конструкцией времени компиляции, а не конструкцией времени выполнения. Невозможно сделать это (легко) во время выполнения, не дожидаясь динамического генерации каждого раза при каждом запуске и имеющего некоторый тип сборки в памяти.
Другая мысль здесь -
Вы можете добиться того же эффекта или достичь этой цели, используя инверсию управления и зависимостей инъекций. Просто заставьте свои классы полагаться на базовый класс или интерфейс. Это упростит изменение реализации позже, во время выполнения, через конфигурацию или многие другие методы.
Вы можете экспортировать "базовые классы" в отдельную DLL и ссылаться на нее в своем проекте. Затем, когда у вас есть новая версия этой DLL, вы просто замените старый.
Но, делая это, вам нужно будет сохранить одно и то же имя для базового класса, и оно будет заменено ВЕЗДЕ к новой версии. Думаю, это не проблема.
Я знаю, что эта ветка довольно старая, но, возможно, этот ответ поможет кому-то в будущем.
Да, это возможно. Сегодня не просто динамическое наследование, но даже многократное наследование возможно (и даже оба одновременно). Вы когда-нибудь слышали о миксинах?
Одним из решений вашей проблемы может быть re-motion, инфраструктура разработки с открытым исходным кодом (которая предоставляет множество замечательных функций, например, использование mixins с С#):
Вы существенно меняете цепочку наследования, чтобы зависеть от новой конкретной реализации. Это вонючий, и хотя это возможно с помощью какого-то кода Emit - я никогда не пробовал этого и склонен согласиться с Джоном С. - Я бы настоятельно советовал ему.
Если вы беспокоитесь о необходимости вводить новые элементы в цепочку наследования, я бы сделал некоторую инкапсуляцию в "OldInheritenceObjectVersion" и ввел в нее фактическую реализацию через Injection Dependency.
Мне все еще не нравится, но это, вероятно, путь наименьшего сопротивления, если вы связаны и решили сделать это через наследование.
Вы можете попробовать что-то вроде этого... не изменяйте структуру наследования по всем подклассам OldInheritanceObjectVersion. Вместо этого измените структуру наследования OldInhertianceObjectVersion в одном месте!
//NewInheritanceObjectVersion
public class NewInheritanceObjectVersion
{ /*
...Move original stuff from OldInheritanceObjectVersion to this class here
...with any new stuff/changes here. Should probably maintain backwards
...compatibility with OldInheritanceObjectVersion if we can
...(or OldInhertianceObjectVersion can be an adapter that maintains backwards
... compatibility and adapts/delegates to this class)
*/
}
//OldInheritanceObjectVersion
public class OldInheritanceObjectVersion : NewInheritanceObjectVersion
{ /*
...Since old and new stuff is implemented in NewInheritanceObjectVersion
...this is simply a "pass-through" class so that all classes that inherit
...from this class get old and new behavior without changing their inheritance
...worst case, this class can expose the old interface/class definition and
...delegate/adapt the methods/properties to the new
...features in NewInheritanceObjectVersion
...if NewInheritanceObjectVersion does not implement them directly
*/
}
//PROGRAM B .....a Few Years Later.....
public class MySuperClass : OldInheritanceObjectVersion
{ /*
........Without changing this at all, we get all old behavior
........and we can update it to take advantage of new features as well
*/
}