各种略有不同的通用对象的列表

时间:2015-03-10 21:49:24

标签: c# generics

我正在将一些代码库合并为一个,并试图找出一种巧妙的方法将一些稍微不同的通用对象合并到一个列表中,该列表构建了一些用于过滤的UI。

我有许多Manager对象可以生成和管理构建在某些应用程序基类之上的ResultSet。

任何想法都会很棒。我试图尽可能不重构旧的深层代码。

CityManager就像

   ImAFilterSetManager<ImAFilterSetBase<CityBase>>

和ChainManger类似

   ImAFilterSetManager<ImAFilterSetBase<ChainBase>>

Manager执行Initialize并返回一个ImAFilterSetBase并连接处理程序。

有没有办法施放到下面这样的东西?

ImAFilterSetManager<ImAFilterSetBase<object>>

执行代码

      List<object> filters = new List<object>() { 
                        new CityManager(),
                        new ChainManager(), }

        //(XXXX as  object fails)
        foreach (ImAFilterSetManager<ImAFilterSetBase<XXXX>> filter in filters) 
        {
               var newFilter = filter.Initialize(_Client);

               filter.OnResultsChanged += filterResults_Handler;
        }

似乎如果使用dyanmic我可以初始化(或者至少它是compliles并且运行,还没有尝试过其他的东西)但是我有点担心这会是不好的形式或导致副作用。

foreach (dynamic filter in filters) 
{           
    var newFilter = filter.Initialize(_Client);
}

参考接口(通用I是ImAFilterSetBase(CityBase),通用C是CityBase或ChainBase类)

public interface ImAFilterSetManager<I>
        {
                event EventHandler<ResultSetArgs> OnResultsChanged;

                I Initialize(IClient client);
        }

        public interface ImAFilterSetBase<C>
        {
                string FilterName { get; set; }

                List<C> Filter { get; set; }
        }

2 个答案:

答案 0 :(得分:2)

在C#中,Generic<A>Generic<B>不相关,除非您将它们相关联。创建另一个非泛型类(或接口) - FilterSetManager,并让您的所有ImAFilterSetManager<T>派生出来,或实现它。

然后你可以拥有List<FilterSetManager>

答案 1 :(得分:0)

您可以在Liskov Substitution原则( SOLID )中思考,因此一种好方法是通过界面关联对象:

//defines the contract
public interface IObjectBase {
    //add signatures
}

class CityBase : IObjectBase /*, IAnotherBaseA */ {
    //implementation
}

class ChainBase : IObjectBase /*, IAnotherBaseB */ {
    //implementation
}

现在我们要为ImAFilterSetBase创建约束并将其重命名为AFilterSetBase

public abstract class AFilterSetBase<T> where T : IObjectBase /*, new() */ {
        public string FilterName { get; set; }
        public IList<T> Filters { get; set; }
}

我将重新定义界面ImAFilterSetManager并将其重命名为IFilterSetManager

public interface IFilterSetManager {
    event EventHandler<ResultSetArgs> OnResultsChanged;
    AFilterSetBase<IObjectBase> Initialize(IClient client);
}

现在我们可以创建实现IFilterSetManager的类:

public class CityManager : IFilterSetManager {
    public AFilterSetBase<IObjectBase> Initialize(IClient client) {
        //TODO: implementation
        throw new NotImplementedException();
    }
}

//other classes that implements IFilterSetManager 
class ChainManager : IFilterSetManager {
    public AFilterSetBase<IObjectBase> Initialize(IClient client) {
        throw new NotImplementedException();
    }
}

最后,在最后一节中,我们可以创建如下列表:

static void Main() {
    IClient _client;
    //_client = new ...

    var filters = new List<IFilterSetManager>() {
        new CityManager(),
        new ChainManager()
    };

    foreach (var item in filters) {
        var newFilter = item.Initialize(_client);
    }
}

实施

CityManager的示例实现如下:

class CityFilter : AFilterSetBase<IObjectBase> {
    public CityFilter(string filterName) {
        this.FilterName = filterName;
        this.Filters = new List<IObjectBase>();
    }
}

public class CityManager : IFilterSetManager {
    public AFilterSetBase<IObjectBase> Initialize(IClient client) {
        var item = new CityFilter("City Filters");
        item.Filters.Add(new CityBase());
        return item;
    }
}

然后我们可以测试它:

    static void Main(string[] args) {
        IClient _client;
        _client = null;

        var filters = new List<IFilterSetManager>() {
            new CityManager(),
            new ChainManager()
        };

        foreach (var item in filters) {
            var newFilter = item.Initialize(_client);
            System.Console.WriteLine("Filter name: " + newFilter.FilterName);
            System.Console.WriteLine("Filters added: " + newFilter.Filters.Count);
        }

        System.Console.ReadLine();
    }