C# 扩展接口

C# 扩展接口,c#,C#,我有一个实现枚举器的接口,类似于 foreach(IClass i in collection) { } 我无法访问IClass或collection的代码,因为它位于我正在构建的库中。现在我想向IClass添加属性。我一直在尝试的是 public class IClassExt : IClass { ... IClass properties ... additional properties } 但是现在我不知道怎么在我打电话的时候得到IClassExt forea

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

foreach(IClass i in collection)
{

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

public class IClassExt : IClass 
{
    ... IClass properties
    ... additional properties
}
但是现在我不知道怎么在我打电话的时候得到IClassExt

 foreach(IClassExt i in collection)
{
}
我尝试了从IClass到IClassExt的转换,但这是不允许的,即使它有效,如果每次使用循环时我都必须这样做,那也太耗时了。我需要能够一次性将所有IClass实现为iClassText,并将我的集合设置为iClassText集合,而不是IClass集合。

看看这是否有效:

var iClassCollection = collection.Select(c=> (ICollectionExt)c).ToList();

foreach(IClassExt i in iClassCollection)
{
   // ... 
}
您可以使用OfType Linq扩展方法在
集合中获取
IClassExt
的实例。这允许
IClass
IClassExt
实例驻留在同一个集合中

示例类和接口设置

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 collection=new-IClass[]{new-Foo{ClassName=“MyFooClass”,IsValid=true},new-Bar{ClassName=“MyBarClass”,IsValid=false,SuperiorClassName=“MySuperiorFooBarClass”};
foreach(collection.OfType()中的IClassExt classExt){
//在这里做些很酷的事
}

您可以声明以下内容:

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

但是:

我需要能够一次性将我的所有IClass实现为IClassExt,并使我的集合成为IClassExt集合而不是IClass集合

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

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


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

能否详细说明“耗时”一词?它有多耗时?如果您正在执行foreach(集合中的IClass i)
,则接口
IClass
不会实现枚举器。无论
collection
是什么类型,它都实现了
IEnumerable
@Thomas Weller:我在考虑尝试类似于foreach(IClass I in collection){IclassExt=(IclassExt)I…,然后用I}做一些事情。但这意味着每次使用循环时都必须分配额外的属性。这就假设
collection
中的所有实例都属于
ICollectionExt
类型。