1

このメソッドをジェネリックにするのに助けが必要です。さまざまなWebリストコントロールのリストを取得するために、約10回繰り返されます(特定のコントロールで使用されるタイプを「MyType」に置き換えます)。

    private static IList<MyType> GetList(RequestForm form)
    {
        // get base list
        IMyTypeRepository myTypeRepository = new MyTypeRepository(new HybridSessionBuilder());
        IList<MyType> myTypes = myTypeRepository.GetAll();

        // create results list
        IList<MyType> result = new List<MyType>();

        // iterate for active + used list items
        foreach (MyType myType in myTypes)
        {
            if (myType.Active || form.SolutionType.Contains(myType.Value))
            {
                result.Add(myType);
            }
        }

        // return sorted results
        result.OrderBy(o => o.DisplayOrder);
        return result;
    }

これだけでは不十分な場合はお知らせください。これには、私が精通している、より高度な言語機能が必要だと思います。たぶん私はそれらすべてに同じリポジトリを使用させるべきですか?

ご協力いただきありがとうございます。

編集:あなたの助けをありがとう。私はピアサポートを持っていないので、このボードは素晴らしく、あなた方一人一人から何かを学びました。私はすべての答えを受け入れることができればいいのにと思います。

4

4 に答える 4

6

まず、次のように関数をもう少し簡潔にすることができます。

private static IList<MyType> GetList(RequestForm form)
{
    // get base list
    IMyTypeRepository myTypeRepository =
        new MyTypeRepository(new HybridSessionBuilder());

    IList<MyType> myTypes = myTypeRepository.GetAll();

    return myTypes.Where(x => x.Active || form.SolutionType.Contains(x.Value))
                  .OrderBy(x => x.DisplayOrder).ToList();
}

その時点で、関数のコンテンツのほとんどはに直接関連しているため、それをさらに改善する方法は、関連する他のタイプとの関連にMyType大きく依存します。MyTypeたとえば、他のタイプが(私にとって)合理的な契約に従っている場合に作成できる架空のバージョンを次に示します。

private static IList<T> GetList(RequestForm form) where T : OrderedValueContainer
{
    // we'll want to somehow genericize the idea of a TypeRepository that can
    // produce these types; if that can't be done, we're probably better off
    // passing a repository into this function rather than creating it here

    var repository = new TypeRepository<T>(new HybridSessionBuilder());
    IList<T> myTypes = repository.GetAll();

    // the hypothetical OrderedValueContainer class/interface
    // contains definitions for Active, Value, and DisplayOrder

    return myTypes.Where(x => x.Active || form.SolutionType.Contains(x.Value))
                  .OrderBy(x => x.DisplayOrder).ToList();
}
于 2009-05-28T13:19:22.577 に答える
4

すべてのタイプが同じインターフェイスを実装している場合(実装されていない場合は、このメソッドで必要なすべてのプロパティをインターフェイスに追加してください)、次のように実行できます。

private static IList<T> GetList(RequestForm form)
       where T: IMyInterface
    {
        // get base list
        IMyTypeRepository myTypeRepository = new MyTypeRepository(new HybridSessionBuilder());
        IList<T> myTypes = myTypeRepository.GetAll();

        // create results list
        IList<T> result = new List<T>();

        // iterate for active + used list items
        foreach (T myType in myTypes)
        {
            if (myType.Active || form.SolutionType.Contains(myType.Value))
            {
                result.Add(myType);
            }
        }

        // return sorted results

        return result.OrderBy(o => o.DisplayOrder).ToList();
    }

私が行ったもう1つの変更は、最後の行です。ここでは、別の行にorderbyがあり、実際にはOrderedリストをキャプチャしていませんでした。

編集:リポジトリの問題を解決するために、Tのタイプに基づいて正しいリポジトリを返すような種類のリポジトリファクトリを作成できます。

public static IMyTypeRepository  GetRepository(Type t)
{
   if(t == typeof(Type1))
   {
      return Type1Repository();
   }

   if(t == typeof(Type2))
   {
      return Type2Repository();
   }
   .......
}

もちろん、すべてのリポジトリがIMyRepositoryインターフェースを実装していると仮定します。

于 2009-05-28T13:14:09.717 に答える
2

まず、すべてのタイプは、、...などのプロパティを定義する共通を実装する必要がありますinterfaceActiveValue

MyTypeまた、私が言えることは、このような一般的な方法を使用できるように、すべてのリポジトリに独立したリポジトリインターフェイスが必要です。GetAll()メソッドはで定義する必要がありますIRepository

public interface IRepository<T> where T : IMyType
{
    IList<T> GetAll();
}

public class RepositoryFactory
{
    public static IRepository<T> createRepository<T>(ISessionBuilder sb) where T : IMyType
    {
        // create repository
    }
}

public interface IMyType
{
    bool Active { get; }
    string Value { get; }
}

private static IList<T> GetList(RequestForm form) where T : IMyType
{
    // get base list
    IRepository<T> repository = RepositoryFactory.createRepository<T>(new HybridSessionBuilder());
    IList<T> myTypes = repository.GetAll();

    // create results list
    IList<T> result = new List<T>();

    // iterate for active + used list items
    foreach (T myType in myTypes)
    {
        if (myType.Active || form.SolutionType.Contains(myType.Value))
        {
            result.Add(myType);
        }
    }

    // return sorted results
    return result.OrderBy(o => o.DisplayOrder).ToList();
}
于 2009-05-28T13:42:09.363 に答える
1

リポジトリが共通のインターフェースを共有していると仮定すると、リポジトリの問題は簡単に修正できるはずです。たとえば、次のような静的関数を追加します。


public static IRepository RepositoryForType(Type t)
{
    if(t == typeof(SomeClass))
       return new SomeClassRepository(new HybridSession());
    else if ...
    else throw new InvalidOperationException("No repository for type " + t.Name);
}

これにより、既存のコードへの変更は最小限で済みますが、将来的には、プロジェクトに新しいリポジトリを追加するときに、この関数で新しいリポジトリのクラスサポートを追加する必要があることに注意してください(単体テストを使用している場合)とにかくこのヘルパーを忘れたかどうかは簡単にわかります)。

于 2009-05-28T13:17:17.963 に答える