1

我有一个类型的私有成员,List<T>其中T是丰富的域对象。我的应用程序中的域包含许多需要T.

我只想公开IList<IT>where类型的公共属性T : ITIT占用空间小,由 DTO 实现。

由于我不能投到List<T>IList<IT>正在诉诸List<T>.ConvertAll于在财产声明中使用。

有没有更好的方法来做到这一点?更快,更优雅?

编辑以提供更多详细信息

它们是一个基类,T存在许多派生类,并且这些派生类中的每一个都有许多不同的风格(在运行时加载的配置)。表示层中的用户可以添加/更改/删除任何配置的这些派生类的任何实例。这些实例也可以由用户定向地相互链接,但是有一些复杂的规则来管理允许的链接;有些在编译时已知,有些仅在运行时已知(基于配置)。一些实例可能是双联的,一些是交联的,一些仅在任一方向上单向,一些仅在一个方向上,而有些则根本没有。

为此,T包含任何此类链接的有效目标列表。表示层以图形方式突出显示这些有效目标,如果目标不在有效列表中,则不允许链接。当新创建、更改或删除任何实例时,每个实例的 ValidTargets 列表需要重新评估并且可能会更改。

T工厂和服务类期望在该类上运行许多其他成员和方法。有些行为与上面的示例非常相似。这些都不应该暴露在组件之外。

4

2 回答 2

0

假设你可以做这样的事情:

// 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实际上是 a List<MyRealClass>,但是编译器不能确保只有 的实例MyRealClass被添加到列表中(它需要运行时检查)。换句话说,这种行为不是类型安全的,因此编译器不会允许。

您可以公开IList/ ICollectionof IMyInterface— 这是类型安全的,但不能确保只有您的MyRealClass被添加到列表中。

public class Domain
{
    private List<IMyInterface> myList;

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

或者,您可以公开IEnumerableof IMyInterface(或IReadOnlyList,如zmbq建议的那样)——因为类型参数是协变的(请参阅泛型中的协变和逆变)。尽管这不允许您将新项目添加到集合中。

public class Domain
{
    private List<MyRealClass> myList;

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

另一种解决方案是实现您自己的集合类,该集合类实际上实现了 ofIList<IMyInterface>但如果用户尝试插入除MyRealClass. 这不是一个特别优雅的解决方案,实际上,它与简单地公开一个IList<MyRealClass>.

于 2013-09-01T17:40:06.457 回答
-1

如果我对您的理解正确,您应该能够使用 Linqs 选择方法将您的列表转换为 IList。所以你正在做类似的事情:

List<T> myList = ...
IList<IT> b = myList.Select(a=> a as IT).ToList();
于 2013-09-07T15:14:00.973 回答