C#类,接口和约束

时间:2012-03-29 12:42:42

标签: c# oop

我有一个项目,我需要实现以下目标:

假设我有一个名为“ITemplate”的界面,我根据该界面定义了许多类“模板”。

  • TemplateA
  • TemplateB
  • ....
  • TemplateZ

如果我想创建任何模板的LIST,我可以使用

List<ITemplate> myList = new List<ITemplate>();
myList.Add(TemplateA);
myList.Add(TemplateC);
myList.Add(TemplateX);

等 - 没关系。

现在说我想创建一些特殊列表,以便

myListAlphaTemplates只能拥有所有模板的已定义子集,并且 myListBetaTemplates只能拥有所有模板的不同定义子集

实现这一目标的最佳方法是什么?

所以我现在的代码是沿着下面的代码(实际代码太大而无法发布)

定义模板界面

interface ITemplateConstraint 
{ }

为每个列表类型定义更多接口

interface SpecialListOne : ITemplateConstraint
{ }

interface SpecialListTwo : ITemplateConstraint
{ }

现在我定义一个实际的“模板”

public class TemplateA : SpecialListOne , SpecialListTwo 
{     ....    }

public class TemplateB : SpecialListOne 
{     ....    }

public class TemplateC : SpecialListTwo 
{     ....    }

最后我添加了我的列表

List<SpecialListOne> ListofTypeOne;   // this can be TemplateA  or TemplateB 
List<SpecialListTwo> ListofTypeTwo;   // this can be TemplateA  or TemplateC 

这很好,但是..

如果所有模板都在一个单独的库中,并且我需要创建一个新的列表“SpecialListThree”,其中只有TemplateC,有没有办法这样做而不必修改实际的模板定义本身?

6 个答案:

答案 0 :(得分:4)

非常简单,任何Enumerable<>都有扩展方法OfType<>

使用它的一个例子是:

var myList = new List<ITemplate>();
myList.Add(TemplateA);
myList.Add(TemplateC);
myList.Add(TemplateX);

var myListAlphaTemplates = myList.OfType<AlphaTemplateClass>().ToList();

答案 1 :(得分:1)

您可以根据ITemplate为您的alpha和beta模板制作界面,并让您的特定类实现这些:

IAlphaTemplate : ITemplate {}

IBetaTemplate : ITemplate {}

TemplateA : IAlphaTemplate {}

TemplateB : IBetaTemplate {}

// etc.

var myListAlphaTemplates = new List<IAlphaTemplate>();
var myListBetaTemplates = new List<IBetaTemplate>();

答案 2 :(得分:1)

如果您希望按Type约束列表,那么您可以使用

等代码
public class MyList<T> : List<T> where T:ITemplate, new() { }  

var specialList1 = new MyList<TemplateA>();
var specialList2 = new MyList<TemplateB>();

如果约束处于任意条件,那么您可能需要编写自己的包装内部列表实现的类。但约束将在运行时而不是编译时发生。例如:

public class ConstrainedList<T> : IList<T> where T:ITemplate
{
    private List<T> _inner = new List<T>();
    Func<T, bool> _constraint;

    public ConstrainedList<T>(Func<T, bool> predicate)
    {
       _constraint = predicate;
    }

    #Region IList Implementation

    public void Add(T item)
    {
        if (_constraint(item))
        {
           _inner.Add(item);
        }
        else
        {
           throw new ArgumentException("Does not meet necessary constraint");
        }
    }

    // rest of implementation
    ...

    #End Region
}

var specialList1 = new ConstrainedList<ITemplate>(t => null != t && typeof(TemplateA) == t.GetType());
var specialList2 = new ConstrainedList<ITemplate>(t => null != t && t.SomeMethod() >= 3);

答案 3 :(得分:0)

如果有任何逻辑,请使特殊类继承自实现接口的抽象特殊类,或使它们实现从常规接口继承的特殊接口。

否则,你无法强迫它。

答案 4 :(得分:0)

您可以定义一个实现接口的抽象类,然后继承该接口以定义具体的实现。

答案 5 :(得分:-1)

interface IQalifiedTemplate
{
     bool IsQaulified(args);
     ITemaplate Template {get;}
}

interface IQalifiedTemplate
   : ITemplate
{
     bool IsQaulified(args);
}

您可以使用IsQualified(...)来确定是否应将其添加到列表中。