0

我需要在某些操作上更新我的 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.
    }
}
  • 由于 POCO 可能实现了很多不同的属性(都具有相应的接口),因此使用不同的函数签名来解决问题几乎是不可能的。
  • 出于性能原因,我宁愿不使用反射。

有什么可行的方法让我摆脱痛苦吗?

4

3 回答 3

4

你需要更多()的铸件:

 // (IHasLastChange)entity.LastChange = DateTime.Now;
   ((IHasLastChange)entity).LastChange = DateTime.Now; 

因为有很多不同的属性

然后使用临时变量将很快得到回报:

if (entity is IHasLastChange)
{
    lastChange = (IHasLastChange) entity;
    lastChange.LastChange = DateTime.Now; 
    lastChange. ... 
}
于 2012-11-01T13:20:11.220 回答
2

执行此操作的常用方法是将实体转换为as并检查它是否为null,如下所示:

var lastChangedEntity = entity as IHasLastChange;
if (lastChangedEntity != null)
{
    lastChangedEntity.LastChange = DateTime.Now;
}

但是随着不同接口数量的增加,这会导致令人讨厌的代码异味。

如果是这种情况,请考虑使用策略模式来处理它,这样您将遵守开放/封闭原则 (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;
        }
    }
}
于 2012-11-01T13:26:36.057 回答
1

你需要投。

var hasLastChange = entity as IHasLastChange;
hasLastChange.LastChange = DateTime.Now; //It works!

或者

((IHasLastChange)entity).LastChange = DateTime.Now; //It also works!
于 2012-11-01T13:20:24.290 回答