2012-11-01 1 views
0

특정 작업에서 내 POCO 엔티티의 특정 속성을 업데이트해야합니다.C# 인터페이스를 구현 한 후에 엔티티의 속성에 액세스하기

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

당신은 주조 () 더 필요 :

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

신속 임시 var에 사용하는 지불 할 다른 속성 그런

의 꽤 많은 거기 때문에 :

if (entity is IHasLastChange) 
{ 
    lastChange = (IHasLastChange) entity; 
    lastChange.LastChange = DateTime.Now; 
    lastChange. ... 
} 
1

캐스팅해야합니다.

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

또는

((IHasLastChange)entity).LastChange = DateTime.Now; //It also works! 
2

는 다음과 같이 null의 경우 as으로 개체를 캐스팅하고 확인하는 것이 작업을 수행하는 일반적인 방법 :

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; 
     } 
    } 
} 
관련 문제