干这个方法

时间:2009-05-28 13:08:37

标签: c# dry

我需要帮助使这个方法通用。重复大约十次以获取不同Web列表控件的列表(将“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 个答案:

答案 0 :(得分: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();
}

答案 1 :(得分: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();
    }

我做的另一个更改是最后一行,您在单独的行上有订单,并且从未实际捕获有序列表。

编辑:要解决存储库问题,您可以拥有一个存储库工厂,它们根据T的类型返回正确的存储库:

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

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

当然假设您的所有存储库都实现了IMyRepository接口。

答案 2 :(得分:2)

首先,您的所有类型都必须实现一个公共interface来定义ActiveValue ...

等属性

另外,就我所知,必须有一个独立于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();
}

答案 3 :(得分: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);
}

这应该要求您对现有代码进行最少量的更改,但请注意,在您的项目中添加新存储库时,将来必须在此函数中添加对新存储库的类支持(如果您是使用单元测试你很容易弄清楚你是否忘记了这个助手。)