#c# #ironpython
#c# #ironpython
Вопрос:
Я пытаюсь добавить поддержку сценариев Python в существующую библиотеку C #, используя IronPython. Однако при попытке использовать методы расширения Linq в одной из моих структур, которая является IEnumerable<T>, я получаю исключение System.Collections.Generic.IEnumerable`1[TSource] contains generic parameters'
, тогда как когда я меняю тип на класс, он работает, как ожидалось.
Вот некоторый переработанный код, который отображает то же поведение. Как упоминалось, изменение A на класс решает проблему, но это привело бы к ненужной генерации мусора в моем реальном коде проекта, поэтому я бы предпочел не прибегать к этому. Я использую IronPython 2.7.9 от Nuget.
using IronPython.Hosting;
using Microsoft.Scripting;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace IronPython279
{
public struct A : IEnumerable<int>
{
public IEnumerator<int> GetEnumerator() => new List<int>(new[] { 1, 2, 3 }).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
class Program
{
static void Main(string[] args)
{
var engine = Python.CreateEngine();
var scope = engine.CreateScope();
var sourceCode = new StringBuilder();
sourceCode.AppendLine("import clr");
sourceCode.AppendLine($"clr.AddReference("{nameof(System)}.Core")");
sourceCode.AppendLine($"clr.AddReference("{nameof(IronPython279)}")");
sourceCode.AppendLine($"import {nameof(System)}");
sourceCode.AppendLine($"import {nameof(IronPython279)}");
sourceCode.AppendLine($"from {nameof(IronPython279)} import {nameof(A)}");
sourceCode.AppendLine($"clr.ImportExtensions({nameof(System)}.{nameof(System.Linq)})");
sourceCode.AppendLine($"a = {nameof(A)}()");
sourceCode.AppendLine($"b = a.{nameof(System.Linq.Enumerable.First)}()");
var source = engine.CreateScriptSourceFromString(sourceCode.ToString(), SourceCodeKind.Statements);
source.Execute(scope);
}
}
}
Что означает эта ошибка (в ней указано что-то, что является правдой, но не почему это проблема) и существуют ли какие-либо другие обходные пути, помимо перехода на класс?
Комментарии:
1. Примечание сбоку: » Как упоминалось, изменение A на класс решает проблему, но это привело бы к ненужной генерации мусора в моем реальном коде проекта » Этот аргумент спорный, поскольку передача (или попытка передать) структуры как
IEnumerable<T>
в любом случае потребовала бы упаковки…2. @elgonzo Хотя в этом случае вы справедливо указываете, реальная структура обладает другими свойствами и может быть просто создана для них, что означает множество случаев, когда упаковка не выполняется.