Как избежать ошибки компиляции с несовместимой доступностью класса и методов? - PullRequest
2 голосов
/ 08 мая 2019

Я размышляю о сборке Autodesk и обнаружил следующее:

enter image description here

Обратите внимание, что для класса PressurePipeNetwork это public,и есть метод AddLinePipe, который также является public.Однако одним из параметров для AddLinePipe, PressurePartSize является internal.

enter image description here

Обычно мы не можем скомпилировать кодкак это (и мы получим ошибку компиляции в виде «Inconsistent Accessibility») в .Net.Но каким-то образом эта сборка сошла с рук.

И я уже проверяю, есть только один PressurePartSize в сборке.

Я не слишком уверен, когда кто-то сказал, что это не может бытьсделанный. Autodesk уже сделал это ;Я получил сборку!

Мало того, можно как-то использовать библиотеку в C #, , но с сообщением об ошибке

Autodesk.Civil.DatabaseServices.Styles.PressurePartSize показывает ошибку, которая доступна в связи с уровнем защиты.

Как это сделать? Я хочу использовать для этого любой язык, а не только C #.или .Net

Ответы [ 2 ]

3 голосов
/ 08 мая 2019

Это не может быть сделано в C #.Однако виртуальная машина .NET более мягкая, чем C #.Есть много функций, которые C # не предоставляет.

На уровне IL вы можете просто вызывать непубличные методы.Вы также можете сделать это с помощью генерации кода во время выполнения с помощью отражения emit.Это очень полезно для создания быстрых сериализаторов.

JIT также способен компилировать непроверяемый и даже неверный IL.Результат не полностью определен.

Как создавалась эта сборка?Моей первой мыслью было, что это результат работы инструмента компоновки IL.Сборки .NET могут быть подвергнуты последующей обработке, чтобы объединить или оптимизировать их.Это также может быть результатом использования инструмента запутывания (особенно метода, который не может быть декомпилирован).

Похоже, что в инструменте есть ошибка, потому что он определенно не является намеренным для создания открытого метода, который обычно не вызывается.

Если вы хотите поэкспериментировать с этим, вы можете декомпилировать любую сборку в IL, редактировать ее и компилировать.ИЛ создан для того, чтобы совершить круговорот во всем, во что я верю.

1 голос
/ 08 мая 2019

Просто предложение. Может быть два PressurePartSize класса: открытый и внутренний. Это не ясно из фотографий.

Примерно так:

namespace SampleLib
{
    using SampleLib.Internal;
    //using SampleLib.Public;

    public class PublicClass
    {
        public unsafe void PublicMethod(InternalClass internalClass) { }
    }
}

namespace SampleLib.Internal
{
    internal sealed class InternalClass { }
}

namespace SampleLib.Public
{
    public sealed class InternalClass { }
}

Ошибка CS0051 Несогласованная доступность: тип параметра «InternalClass» менее доступен, чем метод «PublicClass.PublicMethod (InternalClass)»

Но

namespace SampleLib
{
    //using SampleLib.Internal;
    using SampleLib.Public;

    public class PublicClass
    {
        public unsafe void PublicMethod(InternalClass internalClass) { }
    }
}

namespace SampleLib.Internal
{
    internal sealed class InternalClass { }
}

namespace SampleLib.Public
{
    public sealed class InternalClass { }
}

В порядке.

Обновление

Существует только один PressurePartSize, см. Обновленный вопрос .

Чем кажется, что сначала у них была Autodesk.Civil.DatabaseServices.Styles.PressurePartSize публика . Затем они создали библиотеку с public unsafe ObjectId AddLinePipe(LineSegment3d line, PressurePartSize partSize) и создали ее. Затем они изменили Autodesk.Civil.DatabaseServices.Styles.PressurePartSize на internal , но не восстановили вызывающую библиотеку. Но JIT-компилятор проверяет доступность во время выполнения. Вот причина исключения, которое вы упомянули .

...