[英]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
/ ICollection
的IMyInterface
首位,而其類型安全的,但不保證只有你MyRealClass
被添加到列表中。
public class Domain
{
private List<IMyInterface> myList;
public IList<IMyInterface> Interfaces { get { return this.myList; } }
}
或者,也可以暴露一個IEnumerable
的IMyInterface
(或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.