我需要在某些操作上更新我的POCO实体的某些属性。
我定义了以下接口:
public interface IEntityPOCO
{
Guid Id { get; set; }
}
public interface IHasLastChange : IEntityPOCO
{
DateTime LastChange { get; set; }
}
以下是一个示例操作方法:
public void SomeStuff<T>(T entity) where T : class, IEntityPOCO
{
entity.Id = Guid.NewGuid(); // Works like a charm.
if (entity is IHasLastChange)
{
entity.LastChange = DateTime.Now; // Doesn't work. D'oh.
(IHasLastChange)entity.LastChange = DateTime.Now; // Doesn't work either.
}
}
有没有可行的办法让我摆脱痛苦?
答案 0 :(得分:4)
你需要更多()
投射:
// (IHasLastChange)entity.LastChange = DateTime.Now;
((IHasLastChange)entity).LastChange = DateTime.Now;
因为有很多不同的属性
然后它将很快支付使用temp var:
if (entity is IHasLastChange)
{
lastChange = (IHasLastChange) entity;
lastChange.LastChange = DateTime.Now;
lastChange. ...
}
答案 1 :(得分:2)
执行此操作的常用方法是使用as
投射实体并检查它是否为null
,如下所示:
var lastChangedEntity = entity as IHasLastChange;
if (lastChangedEntity != null)
{
lastChangedEntity.LastChange = DateTime.Now;
}
但随着不同界面数量的增加,这会导致令人讨厌的代码味道。
如果是这种情况,请考虑使用Strategy Pattern来处理它,这样您就会遵守Open/Closed Principle (OCP)并使您的应用程序更易于维护。
编辑:策略模式示例如下:
public void SomeStuff<T>(T entity) where T : class, IEntityPOCO
{
entity.Id = Guid.NewGuid(); // Works like a charm.
// _processors is a List<IProcessEntities>
var processors = _processors.Where(p => p.CanProcess(entity));
foreach (var processor in processors)
{
processor.Process(entity);
}
}
public interface IProcessEntities
{
bool CanProcess<T>(T entity) where T : class, IEntityPOCO;
void Process<T>(T entity) where T : class, IEntityPOCO;
}
public class LastChangedProcessor : IProcessEntities
{
public bool CanProcess<T>(T entity) where T : class, IEntityPOCO
{
return typeof(IHasLastChange).IsAssignableFrom(typeof(T));
}
public void Process<T>(T entity) where T : class, IEntityPOCO
{
var lastChangeEntity = entity as IHasLastChange;
if (lastChangeEntity != null)
{
lastChangeEntity.LastChange = DateTime.Now;
}
}
}
答案 2 :(得分:1)
你需要施放。
var hasLastChange = entity as IHasLastChange;
hasLastChange.LastChange = DateTime.Now; //It works!
或者
((IHasLastChange)entity).LastChange = DateTime.Now; //It also works!