簡體   English   中英

公開清單 <domain objects> 通過IList <interface>

[英]Exposing a List<domain objects> via an IList<interface>

我有一個List<T>類型的私有成員,其中T是富域對象。 我的應用程序中的域包含許多期望T方法。

我只想公開IList<IT>類型的公共屬性,其中T : IT IT占用的空間很小,由DTO實施。

既然不能投了List<T>IList<IT>我訴諸使用List<T>.ConvertAll在財產申報。

這有更好的方法嗎? 更快,更優雅?

編輯以提供其他詳細信息

T是一個基類,針對該基類存在許多派生類,並且這些派生類中的每一個都有許多不同的風格(在運行時加載配置)。 表示層中的用戶可以添加/更改/刪除任何配置的這些派生類的任何實例。 實例也可以由用戶定向鏈接到彼此,但是有一些復雜的規則來控制允許哪些鏈接; 有些是在編譯時已知的,有些是僅在運行時已知的(基於配置)。 有些實例可能是雙向鏈接的,有些則是交聯的,有些只能在任一方向上是單個的,有些只能在一個方向上,有些根本沒有。

為此, T包含任何此類鏈接的有效目標的列表。 表示層以圖形方式突出顯示這些有效目標,並且如果目標不在有效列表中,則不允許鏈接。 當新創建,更改或刪除任何實例時,需要重新評估每個實例的ValidTargets列表,並且可能會更改。

T類上還有許多其他成員和方法,工廠類和服務類希望在這些類上進行操作。 一些行為與上面的示例非常相似。 這些都不應暴露在組件外部。

假設您可以執行以下操作:

// NOT REAL CODE
public interface IMyInterface { } 
public class MyRealClass : IMyInterface { } 

...

public class Domain
{
    private List<MyRealClass> myList;

    public IList<IMyInterface> Interfaces { get { return (IList<IMyInterface>)this.myList; } }
}

是什么阻止該Domain類的用戶執行此操作?

public class MyFakeClass : IMyInterface { } 

...

domain.Interfaces.Add(new MyFakeClass());

顯然,這是有問題的,因為myList實際上是List<MyRealClass> ,但是編譯器無法確保僅將MyRealClass實例添加到列表中(這需要運行時檢查)。 換句話說,這種行為不是類型安全的,因此編譯器將不允許這樣做。

您可以暴露出IList / ICollectionIMyInterface首位,而其類型安全的,但不保證只有你MyRealClass被添加到列表中。

public class Domain
{
    private List<IMyInterface> myList;

    public IList<IMyInterface> Interfaces { get { return this.myList; } }
}

或者,也可以暴露一個IEnumerableIMyInterface (或IReadOnlyList ,如zmbq建議) -由於所述類型參數是協變(參見協變和逆變在泛型 )。 盡管這不允許您將新項目添加到集合中。

public class Domain
{
    private List<MyRealClass> myList;

    public IEnumerable<IMyInterface> Interfaces { get { return this.myList; } }
}

另一種解決方案是實現您自己的集合類,該集合類實際上實現了IList<IMyInterface>但是如果用戶嘗試插入MyRealClass以外的其他任何東西,則拋出異常。 這不是一個特別優雅的解決方案,實際上,它與簡單地暴露IList<MyRealClass>沒有什么不同。

如果我對您的理解正確,則應該可以使用Linqs select方法將列表轉換為IList。 因此,您正在執行以下操作:

List<T> myList = ...
IList<IT> b = myList.Select(a=> a as IT).ToList();

暫無
暫無

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

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