0

設計時に、Linq式として渡されるプロパティタイプを検出し、そのタイプの評価に基づいてインターフェイスを返すことができる流暢なインターフェイスを作成しようとしています。

例えば:

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

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

CanSearchMethod内で、次のようなことができるようにしたいと思います。

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;
}

異なるインターフェイスのIncludeメソッドとExcludeメソッドは、引数として受け入れられる列挙型のみが異なります。

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);
}

これは不可能だと思いますが、ダイナミクスはファンキーな魔法をかけることができるので、完全に解決することはできません。

他の流暢なインターフェースを見てきましたが、設計中に返すタイプを決定するために式を評価するものはないようです。

4

2 に答える 2

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>煩わしいほど柔軟性のないジェネリックが必要になります。

于 2013-02-26T21:11:00.480 に答える
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)はオブジェクトを返しますが、はIStringOperationsオブジェクトCanSearch(x => x.Age)を返しINumericOperationsます。

于 2013-02-26T21:12:19.983 に答える