2013-02-26 2 views
0

디자인 타임에 Linq 식으로 전달되는 속성 형식을 감지하고 해당 형식의 평가를 기반으로 인터페이스를 반환 할 수있는 유창한 인터페이스를 작성하려고합니다. 다른 인터페이스는 만 ​​다른위한 방법을 포함 및 제외디자인 타임에 동적으로 인터페이스 반환

public IOperations CanSearch(Expression<Func<T, object>> expression) 
{ 
    var type = (/* Code to pick apart expression */); 

    if(type == typeof(int)) 
     return new ClassImplementingINumericOperations(); 
    if(type == typeof(string)) 
     return new ClassImplementingIStringOperations(); 
    if(type == typeof(IEnumerable)) 
     return new ClassImplementingIIEnumerableOperations(); 

    return null; 
} 

: 예를 들어

:

public class Searchable<Person> 
{ 
    public Searchable() 
    { 
     CanSearch(x => x.Name) 
      .Include(StringOperations.Contains); 

     CanSearch(x => x.Age) 
      .Exclude(NumericOperators.GreaterThan); 
    } 
} 

CanSearchMethod 내, 내가 뭔가를 할 수 있도록하고 싶습니다 열거 형 인수로 받아 들여짐 :

public interface IOperations 
{ 
} 

public interface INumericOperations : IOperations 
{ 
    INumericOperations Include(NumericOperationsEnum op); 
    INumericOperations Exclude(NumericOperationsEnum op); 
} 

public interface IStringOperations : IOperations 
{ 
    IStringOperations Include(StringOperationsEnum op); 
    IStringOperations Exclude(StringOperationsEnum op); 
} 

public interface IIEnumerableOperations : IOperations 
{ 
    IIEnumerableOperations Include(CollectionOperationsEnum op); 
    IIEnumerableOperations Exclude(CollectionOperationsEnum op); 
} 

나는 이것이 가능하지 않다고 생각하지만, 다이나믹이 펑키 한 마술을 할 수 있기 때문에 그렇습니다.

다른 유창한 인터페이스를 살펴 보았지만 디자인 중에 반환 할 형식을 결정하기 위해 표현을 평가하는 것으로 보이지는 않습니다.

답변

1

당신은 컴파일시 타입 안전 사용하여 오버로드와 함께이 작업을 수행 할 수 있습니다

public IStringOperations CanSearch<T>(Expression<Func<T, string>> expression); 
public IIEnumerableOperations<TItem> CanSearch<T, TItem>(Expression<Func<T, IEnumerable<TItem>> expression); 

그러나, 숫자 유형, 당신은 7 개 숫자 유형 각각에 대해 별도의 과부하, 또는 일반을해야 하나 INumericOperations<TNumber>은 불편을 겪을 수 있습니다.

1

오버로드 및 형식 유추를 악용 할 수 있습니다. 이런 식으로 뭔가가 :

IStringOperations CanSearch(
    Expression<Func<T, string>> expression) 
{ /* ... */ } 

INumericOperations CanSearch<TCompare>(
    Expression<Func<T, TCompare>> expression) 
    where TCompare : IComparable<TCompare> 
{ /* ... */ } 

IIEnumerableOperations CanSearch<TSeq>(
    Expression<Func<T, IEnumerable<TSeq>>> expression) 
{ /* ... */ } 

이제 CanSearch(x => x.Name)INumericOperations 객체를 반환하는 IStringOperationsCanSearch(x => x.Age) 반면를 반환합니다.

+0

저는 이것을 시험해 보겠습니다. 감사! –