如何在IronPython中使用C#对象上的特定接口

本文关键字:对象 接口 IronPython | 更新日期: 2023-09-27 17:57:31

我有一个C#类,它实现了2个IEnumerable接口。如何从IronPython访问任一接口?

我的班级:

public class MyClass : IEnumerable<TypeA>, IEnumerable<TypeB>
{
    IEnumerator<TypeA> IEnumerable<TypeA>.GetEnumerator()
    {
        return _lstTypeA.GetEnumerator();
    }
    IEnumerator<TypeB> IEnumerable<TypeB>.GetEnumerator()
    {
        return _lstTypeB.GetEnumerator();
    }
}

我在Python中尝试了以下操作,但尽管它运行时没有错误,但它不会从IEnumerable接口返回任何元素:

x = MyClass()
xA = clr.Convert(x, IEnumerable[TypeA])
for y in xA: print y

如何在IronPython中使用C#对象上的特定接口

我不喜欢你的类设计。特别是实现了返回不同成员的两个不同版本的IEnumerable<T>。返回相同成员的两个版本稍微好一点,但我仍然不太喜欢。

  1. 实现IEnumerable使其与两个IEnumerable<T>一致在这里是不可能的。特别是打破了OfTypeCast的linq方法
  2. 你几乎到处都会遇到过载解决问题。像Select<T>(this IEnumerable<T> ...)这样的方法不知道该使用哪个IEnumerable
  3. 不能在MyClass上使用foreach
  4. 如果TypeATypeB都是参考类型,那么IEnumerable<out T>的方差就会反噬你。因为他们都为所有共同的祖先提供IEnumerable<T'>
  5. 它不能很好地与动态类型语言交互
  6. 一个类同时是两个不同的集合很少有意义。它通常表示在从概念到类的映射中出现了问题
  7. 这让人困惑和难以理解。我的直觉告诉我这是邪恶的,我应该用火把它烧了:P

可能还有几个问题我还没想到。


解决方法简单明了:有两个独立的可枚举属性。

public class MyClass
{
  public IEnumerable<TypeA> TypeAs{get{_lstTypeA.Select(x=>x)}};
  public IEnumerable<TypeB> TypeBs{get{_lstTypeB.Select(x=>x)}};
}

您需要像使用反射一样调用方法和属性(这实际上是在后台发生的)。

在你的情况下,你应该做:

x = MyClass()
enumerator = IEnumerable[TypeA].GetEnumerator(x)

然后你可以在enumerator:上循环

for y in enumerator:
   print y

如何使用指定的接口

clr.AddReference('Platform.CardHost')
from Platform import CardHost
from Platform.CardHost import ICardHost
host = CardHost.CardHost.CreateInstance('session')
# ICardHost is interface
# inside C# 
# public interface ICardHost {
# IExtensionManager ExtensionManager { get; }
em = ICardHost.ExtensionManager.__get__(host)