Что я делаю сейчас:
void Main()
{
var command1 = new PersistenceCommand(new MyIntBO());
var command2 = new PersistenceCommand(new MyGuidBO());
var command3 = new PersistenceCommand(new PersistentBO());
Console.WriteLine(command1.ToString());
Console.WriteLine(command2.ToString());
Console.WriteLine(command3.ToString());
}
public class PersistenceCommand
{
public PersistenceCommand(PersistentBO businessObject)
{
_businessObject = businessObject;
}
public override string ToString()
{
string result = _businessObject.GetType().Name;
var keyed = _businessObject as IPrimaryKeyed<int>;
if (keyed != null)
{
result += " " + keyed.Id.ToString();
}
return result;
}
private readonly PersistentBO _businessObject;
}
public interface IPrimaryKeyed<out TKey>
{
TKey Id { get; }
}
public class PersistentBO {}
public class MyIntBO : PersistentBO, IPrimaryKeyed<int>
{
public int Id { get { return 1008; } }
}
public class MyGuidBO : PersistentBO, IPrimaryKeyed<Guid>
{
public Guid Id
{
get
{
return new Guid("6135d49b-81bb-43d4-9b74-dd84c2d3cc29");
}
}
}
Это печатает:
MyIntBO 1008
MyGuidBO
PersistentBO
Я бы хотел напечатать:
MyIntBO 1008
MyGuidBO 6135d49b-81bb-43d4-9b74-dd84c2d3cc29
PersistentBO
Что такоесамый элегантный способ сделать это?
Я хочу поддерживать все типы клавиш - int
, long
, Guid
и т. д., поэтому я бы предпочел не делать несколько приведений.Обратите внимание, что не каждый бизнес-объект реализует этот интерфейс (некоторые не имеют единственного первичного ключа).
Я понимаю, что мог бы использовать отражение и попытаться получить доступ к свойству Id
.Мне было интересно, есть ли лучшее решение.
Пояснение: Чтобы ответить на ответы @Acaz Souza и @Petar Ivanov, у нас есть десятки классов, разбросанных по нескольким сборкам, которые уже реализуют IPrimaryKeyed<T>
.Я не хочу нарушать их все, продлевая контракт на интерфейс.Если бы я проектировал это с нуля, их решения работали бы.