簡體   English   中英

C#類,接口和約束

[英]C# Classes, Interfaces and Constraints

我有一個項目需要實現以下目標:

假設我有一個名為“ ITemplate”的接口,並基於該接口定義了許多類“模板”。

  • TemplateA
  • TemplateB
  • ....
  • TemplateZ

如果我想創建任何模板的列表,可以使用

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 

這很好,但是..

如果所有模板都在一個單獨的庫中,並且我需要創建一個僅包含TemplateC的新列表“ SpecialListThree”,是否有辦法做到這一點而不必自己修改實際的模板定義?

它非常簡單,任何Enumerable<>都有擴展方法OfType<>

其用法的一個示例是:

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

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

您可以基於ITemplate為alpha和beta模板創建接口,並讓您的特定類實現這些接口:

IAlphaTemplate : ITemplate {}

IBetaTemplate : ITemplate {}

TemplateA : IAlphaTemplate {}

TemplateB : IBetaTemplate {}

// etc.

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

好吧,如果您想按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);

如果有任何邏輯,則使特殊類從實現該接口的抽象特殊類繼承,或者使它們實現從常規接口繼承的特殊接口。

否則,您將無法強制執行。

您可以定義一個實現該接口的抽象類,然后從該類繼承以定義您的具體實現。

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

要么

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

您可以使用IsQualified(...)確定是否應將其添加到列表中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM