c # RuntimeBinderException при использовании динамической переменной для обработки внутренних типов.Как я могу это исправить? - PullRequest
0 голосов
/ 21 февраля 2019

Я использую не полностью раскрытый API в надстройке, которую я сейчас пишу.Некоторые классы все еще остаются внутренними, хотя для некоторых открытых методов требуются параметры этих типов.

Для решения проблемы я попытался использовать динамическую типизацию с помощью вспомогательной реализации DymamicObject.Я был довольно успешным, но в какой-то момент я получил RuntimeBinderException, который не сообщает мне точные детали: «Лучший перегруженный метод соответствует Autodesk.Civil.DatabaseServices.PressurePipeNetwork.AddLinePipe (Autodesk.AutoCAD.Geometry.LineSegment3d,Autodesk.Civil.DatabaseServices.Styles.PressurePartSize) 'имеет несколько недопустимых аргументов ".

Во время отладки я вижу, что моя динамическая переменная имеет ожидаемый тип и является допустимым объектом в целом - содержит ожидаемую информацию вего свойства.

Как я могу решить проблему? Как я могу проверить, что именно не так с этим вызовом метода?

Ниже текущегокод (метод AddLinePipe вызывает исключение)

var network = (PressurePipeNetwork)tr.GetObject(networkId, OpenMode.ForWrite);

                var pressurePartList = doc.Styles.GetPressurePartListsExt() as StyleCollectionBase;
                var myListId = pressurePartList["My Parts"];
                var myList = tr.GetObject(myListId, OpenMode.ForRead);

                dynamic exposedPartsList = new ExposedPressureObject(myList);
                dynamic myPipes = exposedPartsList.GetParts(PressurePartDomainType.Pipe);
                dynamic myPipesExposed = new ExposedPressureObject(myPipes);
                dynamic pipe = myPipesExposed[0];

                LineSegment3d line = new LineSegment3d(new Point3d(30, 9, 0), new Point3d(33, 8, 0));
                //here is the public method, requirng a variable of internal type
                network.AddLinePipe(line, pipe);

Ниже реализации DymamicObject:

class ExposedPressureObject : DynamicObject
{
    private object _object;
    private IEnumerable<object> _listObject = new List<object>();

    public ExposedPressureObject(object obj)
    {
        System.Collections.IEnumerable enumerable = obj as System.Collections.IEnumerable;
        if (enumerable == null)
            _object = obj;
        else
            _listObject = enumerable.Cast<object>();
    }

    public override bool TryInvokeMember(
            InvokeMemberBinder binder, object[] args, out object result)
    {
        // Find the called method using reflection
        var methodInfo = _object.GetType().GetMethod(
            binder.Name,
            new[] { args[0].GetType() });

        // Call the method
        result = methodInfo.Invoke(_object, args);
        return true;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        PropertyInfo propInfo = _object.GetType().GetProperty(binder.Name,
            BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
        result = propInfo.GetValue(_object , null);
        return true;
    }

    public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
    {
        int index = (int)indexes[0];
        result = _listObject.ToList()[index];
        return true;
    }
}
...