C#类、接口和约束
本文关键字:约束 接口 | 更新日期: 2023-09-27 18:29:28
我有一个项目需要实现以下目标:
假设我有一个名为"ITemplate"的接口,并基于该接口定义了许多类"templates"。
- 模板A
- 模板B
- 模板Z
如果我想创建任何模板的列表,我可以使用
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,有没有一种方法可以做到这一点,而不必修改实际的模板定义本身?
它非常简单,任何Enumerable<>
都有扩展方法OfType<>
。
其使用的一个例子是:
var myList = new List<ITemplate>();
myList.Add(TemplateA);
myList.Add(TemplateC);
myList.Add(TemplateX);
var myListAlphaTemplates = myList.OfType<AlphaTemplateClass>().ToList();
如果您想通过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);
您可以基于ITemplate为alpha和beta模板创建接口,并让您的特定类实现这些接口:
IAlphaTemplate : ITemplate {}
IBetaTemplate : ITemplate {}
TemplateA : IAlphaTemplate {}
TemplateB : IBetaTemplate {}
// etc.
var myListAlphaTemplates = new List<IAlphaTemplate>();
var myListBetaTemplates = new List<IBetaTemplate>();
如果有任何逻辑,请使特殊类从实现接口的抽象特殊类继承,或者使它们实现从常规接口继承的特殊接口。
否则,您将无法提供信息。
您可以定义一个实现接口的抽象类,然后从中继承来定义您的具体实现。
interface IQalifiedTemplate
{
bool IsQaulified(args);
ITemaplate Template {get;}
}
或
interface IQalifiedTemplate
: ITemplate
{
bool IsQaulified(args);
}
您可以使用IsQualified(…)来确定是否应将其添加到列表中。