На моем бизнес-уровне мне нужно много, много методов, которые следуют шаблону:
public BusinessClass PropertyName
{
get
{
if (this.m_LocallyCachedValue == null)
{
if (this.Record == null)
{
this.m_LocallyCachedValue = new BusinessClass(
this.Database, this.PropertyId);
}
else
{
this.m_LocallyCachedValue = new BusinessClass(
this.Database, this.Record.ForeignKeyName);
}
}
return this.m_LocallyCachedValue;
}
}
Я все еще изучаю C # и пытаюсь найти лучший способ написать этот шаблон один раз и добавить методы к каждому классу бизнес-уровня, которые следуют этому шаблону, с заменой правильных типов и имен переменных.
BusinessClass - это имя типа, которое необходимо заменить, а PropertyName, PropertyId, ForeignKeyName и m_LocallyCachedValue - все переменные, которые должны быть заменены.
Здесь можно использовать атрибуты? Мне нужно отражение? Как мне написать предоставленный мною скелет в одном месте, а затем просто написать строку или два, содержащие параметры подстановки, и заставить шаблон распространяться сам?
РЕДАКТИРОВАТЬ: изменил мой вводящий в заблуждение заголовок - я надеюсь найти решение, которое не включает в себя методы генерации кода или копирования / вставки, а скорее, чтобы иметь возможность написать скелет кода в базовом классе в некоторых сформировать и сделать так, чтобы он был "реализован" в виде множества подклассов как средство доступа к различным свойствам.
РЕДАКТИРОВАТЬ: Вот мое решение, как предложено, но оставлено невыполненным выбранным ответчиком.
// I'll write many of these...
public BusinessClass PropertyName
{
get
{
return GetSingleRelation(ref this.m_LocallyCachedValue,
this.PropertyId, "ForeignKeyName");
}
}
// That all call this.
public TBusinessClass GetSingleRelation<TBusinessClass>(
ref TBusinessClass cachedField, int fieldId, string contextFieldName)
{
if (cachedField == null)
{
if (this.Record == null)
{
ConstructorInfo ci = typeof(TBusinessClass).GetConstructor(
new Type[] { this.Database.GetType(), typeof(int) });
cachedField = (TBusinessClass)ci.Invoke(
new object[] { this.Database, fieldId });
}
else
{
var obj = this.Record.GetType().GetProperty(objName).GetValue(
this.Record, null);
ConstructorInfo ci = typeof(TBusinessClass).GetConstructor(
new Type[] { this.Database.GetType(), obj.GetType()});
cachedField = (TBusinessClass)ci.Invoke(
new object[] { this.Database, obj });
}
}
return cachedField;
}