У меня есть куча данных, которые я хочу создать в классе, и для каждой переменной я хочу убедиться, что определенный набор методов также определен. IE:
[TypeA] VarA
[TypeB] VarB
[TypeC] VarC
FA1() which is a function of VarA and VarB
FA2() which is a function of VarA and VarC
FB1() which is a function of VarB and VarA
FB2() which is a function of VarB and VarC
...
Поскольку будет большое количество переменных (и, следовательно, еще больше функций), я хочу разделить мой исходный код на управляемые куски. Поэтому я ищу автоматический способ обеспечения создания всех функций для каждой переменной.
Я предложил 3 возможных метода организации своего кода, и я не слишком доволен каждым из них, и я ищу или советую, какой метод лучше (или даже если я пропустил совершенно другой метод реализации) ):
1. Частичный класс
partial class Base
{
}
partial class Base
{
[TypeA] VarA;
FA1 { .. }; // function of VarA and VarB
FA2 { .. }; // function of VarA and VarC
}
partial class Base
{
[TypeB] VarB;
FB1 { .. }; // function of VarB and VarA
FB2 { .. }; // function of VarB and VarC
}
Плюсы:
- Простой
- Переменные доступны только из класса Base.
- Если есть две переменные одного типа, то функции для каждой переменной могут реализовывать свою собственную функцию по-разному.
Минусы:
- Невозможно автоматически убедиться, что все функции созданы для каждой переменной
- Необходимо вручную убедиться, что между именами функций нет конфликтов имен.
Обратите внимание, что минусы могут быть решены с помощью генератора кода какого-то рода (может быть, время, чтобы изучить T4 ??)
2. Внутренний класс
class Base
{
internal [ClassA] ObjA = new [ClassA]();
internal [ClassB] ObjB = new [ClassB]();
}
class [BaseClassA]
{
public [TypeA] VarA;
public virtual F1 { .. };
public virtual F2 { .. };
}
class [ClassA] : [BassClassA]
{
public override F1 { .. }; // function of VarA and ObjB.VarB
public override F2 { .. }; // function of VarA and ObjC.VarC
}
...
Плюсы:
- Иерархия классов обеспечивает создание всех функций и доступ к переменным.
- Посредством использования виртуальных функций можно создавать экземпляры, специфичные для реализации функций
Минусы:
- Использование Внутренний означает, что данные видны везде в сборке.
3. Статические данные
abstract class Data
{
static [TypeA] VarA;
static [TypeB] VarB;
...
}
abstract class [BaseClassA] : Data
{
public virtual F1 { .. };
public virtual F2 { .. };
}
class [ClassA] : [BassClassA]
{
public override F1 { .. }; // function of VarA and VarB
public override F2 { .. }; // function of VarA and VarC
}
class Base
{
[ClassA] ObjA = new [ClassA]();
[ClassB] ObjB = new [ClassB]();
}
Плюсы:
- Система гарантирует, что все подпрограммы будут созданы
- Данные не обрабатываются по всей сборке
- Внутри каждой функции вы можете напрямую ссылаться на другие переменные в соответствии с решением «частичного класса»
Минусы:
- Использование static пахнет так, будто я только что заново изобрел глобальные данные.
Что я хочу, так это как-то черри выбрать лучшие пункты каждого метода:
- Прямой способ доступа к переменным методов "Partial class" и "Static"
- Локальные данные метода "Частичный класс"
- Автоматическое принудительное выполнение функции "Внутренний" и "Статический" методы.
И я хочу избежать:
- Отсутствие принудительной генерации функций в "Частичном классе"
- Глобальный доступ к данным в «внутреннем» методе
- Переосмысление глобальных данных в «статическом» методе
Если бы у меня были мои барабанщики, я бы сказал, что я хочу как-то применить интерфейс к экземпляру переменной - например:
[TypeA] VarA : IFunctions;
[TypeB] VarB : IFunctions;
И каким-то образом компилятор автоматически сгенерирует окончательные имена функций из имен интерфейсов и допустимого имени.
Таким образом, люди могут предложить, какой из 3 методов они предпочтут реализовать, или предложить любые другие методы, которые могут подойти.