Как использовать определенный интерфейс на объекте C # в IronPython - PullRequest
2 голосов
/ 21 мая 2011

У меня есть класс 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 ]

5 голосов
/ 21 мая 2011

Мне не нравится твой дизайн класса.В частности, вы реализуете две разные версии IEnumerable<T>, которые возвращают разных членов.Две версии, которые возвращают одни и те же члены, немного лучше, но мне все еще не очень нравится.

  1. Реализация IEnumerable, так что это совместимо с обоими IEnumerable<T> здесь невозможно.В частности, это нарушает методы OfType и Cast linq.
  2. Проблемы с разрешением перегрузки возникают практически везде.Такие методы, как Select<T>(this IEnumerable<T> ...), не знают, какой IEnumerable взять.
  3. Вы не можете использовать foreach на MyClass
  4. Если оба TypeA и TypeB являютсяТипы ссылок дисперсия 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)}};
}
4 голосов
/ 21 мая 2011

Вам нужно вызывать методы и свойства так же, как вы использовали отражение (на самом деле это то, что происходит внутри).

В вашем случае вы должны сделать:

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

затемВы можете зациклить enumerator:

for y in enumerator:
   print y
0 голосов
/ 26 октября 2016

как использовать указанный интерфейс

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) 
...