扩展接口

本文关键字:接口 扩展 | 更新日期: 2023-09-27 18:17:50

我有一个实现枚举器的接口,类似于

foreach(IClass i in collection)
{
}

我无法访问icclass或collection的代码,因为它位于我正在构建的库中。现在我想给icclass添加属性。我一直在尝试的是

public class IClassExt : IClass 
{
    ... IClass properties
    ... additional properties
}

但是现在我不知道如何得到一个IClassExt当我调用

 foreach(IClassExt i in collection)
{
}

我尝试了从IClass到IClassExt的转换,但这都是不允许的,即使它有效,如果我每次使用循环都要这样做,那就太耗时了。我需要能够实现所有我的IClass作为IClassExt一次,并使我的集合IClassExt集合,而不是一个IClass集合。

扩展接口

您可以使用OfType<> Linq扩展方法来获取collectionIClassExt的实例。这允许IClassIClassExt实例驻留在同一个集合中。

类和接口设置示例

public interface IClass{
    string ClassName {get;set;}
    bool IsValid {get;set;}
}
public interface IClassExt:IClass{
    string SuperiorClassName {get;set;}
}
public class Foo: IClass{
    public string ClassName {get;set;}
    public bool IsValid {get;set;}
}
public class Bar: IClassExt{
    public string ClassName {get;set;}
    public bool IsValid {get;set;}
    public string SuperiorClassName {get;set;}  
}

用法:

var collection = new IClass[]{new Foo{ClassName = "MyFooClass", IsValid=true}, new Bar{ClassName="MyBarClass", IsValid=false, SuperiorClassName = "MySuperiorFooBarClass"}};
foreach (IClassExt classExt in collection.OfType<IClassExt>()){
    //Do something really cool here
}

看看是否有效:

var iClassCollection = collection.Select(c=> (ICollectionExt)c).ToList();
foreach(IClassExt i in iClassCollection)
{
   // ... 
}

你陈述如下:

我无法访问icclass或collection的代码,因为它位于我正在构建的库中。

然后:

我需要能够实现我所有的IClass作为IClassExt一次,并使我的集合一个IClassExt集合而不是一个IClass集合。

如果你没有集合的源,那么你就不能使它成为IClassExt的集合。它将始终是一个IClass的集合,但也可以包含IClassExt,就像List可以包含字符串(或从object继承的任何其他东西)一样。假设集合中的所有内容都是IClassExt是不安全的,因为虽然可以保证每个IClassExt也是一个IClass,但不能保证每个IClass都是一个IClassExt,即使您亲自以这种方式编写了所有代码,您也不能确保下一个处理您代码的人不会决定将其他IClass对象扔到集合中。这意味着,为了安全编码,您必须测试集合中的对象是否为IClassExt。

使用另一个答案中引用的"OfType"扩展方法是确保访问集合时安全性的好方法。另一种可能是使用包装器类来插入和访问集合。

在我看来,最好的选择是创建自己的IClassExt集合并使用它。更改所有代码以使用IClassExt而不是IClass所涉及的工作是在构建应用程序时需要解决的问题。