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

时间:2011-05-21 10:29:17

标签: c# ironpython

我有一个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

3 个答案:

答案 0 :(得分:5)

我不喜欢你的班级设计。特别是您实现了两个不同版本的IEnumerable<T>,它们返回不同的成员。返回相同成员的两个版本稍好一些,但我仍然不喜欢那么多。

  1. 这里实现IEnumerable以使其与IEnumerable<T>两者一致是不可能的。特别是打破了OfTypeCast linq方法。
  2. 几乎在任何地方都会遇到过载解决问题。像Select<T>(this IEnumerable<T> ...)这样的方法不知道要采用哪个IEnumerable
  3. 您无法在foreach
  4. 上使用MyClass
  5. 如果TypeATypeB都是引用类型,则IEnumerable<out T>的方差会回来咬你。因为他们都为他们共同的祖先提供IEnumerable<T'>
  6. 它与动态类型语言无法很好地交互
  7. 同时作为两个不同集合的类很少有意义。它通常表示从概念到类的映射出错了。
  8. 令人困惑且难以理解。我的直觉告诉我这是邪恶的,我应该用火烧它:P
  9. 可能还有几个我还没有想到的问题。


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

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

答案 1 :(得分:4)

你需要在使用反射时调用方法和属性(实际上它是在引擎盖下发生的事情)。

在你的情况下你应该这样做:

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

然后你可以循环enumerator

for y in enumerator:
   print y

答案 2 :(得分:0)

我如何使用指定的界面

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)