Как вы «переопределяете» внутренний класс в C#?

#c# #overriding #internal-class

Вопрос:

Есть кое-что, что я хочу настроить в System.Web.Script.Услуги.ScriptHandlerFactory и другие материалы .NET внутри внутреннего класса. К сожалению, это внутренний класс. Какие параметры у меня есть при попытке настроить метод в этом классе?

Комментарии:

1. Вам действительно не следует этого делать, так как владелец класса пометил его как внутренний (читайте.. не расширяйте, так как я могу изменить его позже/ Он находится в процессе работы / еще не лучший). Создайте свою собственную копию класса и используйте, если вам действительно нужно.

Ответ №1:

Вы можете найти эту недавнюю статью поучительной. В основном, в нем говорится , что вы не можете переопределить ничего помеченного internal , и источник является настолько авторитетным, насколько он становится. Лучшее, на что вы можете надеяться, — это метод расширения.

Комментарии:

1. Блог Эрика Липперта-отличный ресурс, я следил за ним в течение многих лет.

Ответ №2:

Внутреннее ключевое слово означает, что единица кода (класс, метод и т. Д.) является «открытой» для сборки, в которой она находится, но закрытой для любой другой сборки.

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

Короче говоря: вы должны быть СОЛЕМ.

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

 using System;
...
using System.Web.Script.Services

namespace MyGreatCompany.ScriptServices 
{
    public class MyScriptHandlerFactory /* implement all the interfaces */
    {
        private ScriptHandlerFactory internalFactory;
        public MyScriptHandlerFactory()
        {
            internalFactory = new ScriptHandlerFactory();
        }
        ...
    }
}
 

Это может сделать возможным то, чего вы хотите достичь, но это будет некрасиво.

Ответ №3:

Я считаю, что вы можете использовать отражение, чтобы обойти модификаторы доступа в классе, поэтому, возможно, вы можете использовать Отражение.Эмиссия для создания типа, который наследуется от внутреннего типа (но НЕ от модификатора sealed), хотя я не могу найти пример этого в Интернете.

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

Комментарии:

1. Это также, вероятно, работает только тогда, когда вы работаете под полным доверием. Любой контекст, требующий проверки, потерпит неудачу, если вы нарушите контроль доступа.

2. Этот подход также не работает, за исключением такого исключения, как System. Исключение загрузки типа : Метод «MyOverridingMethod» для типа «MyClass» из сборки «MyAssembly, Версия=0.0.0.0, Культура=нейтральная, PublicKeyToken=null» переопределяет метод, который не виден из этой сборки.

Ответ №4:

Это зависит от сборки. Это может привести к нарушению некоторых лицензий (хотя это похоже на какую-то статическую привязку) и, возможно, даже превратит развертывание в кошмар, но вы могли бы рассмотреть возможность:

  • Декомпилируйте и скопируйте код в свой собственный проект; при необходимости измените
  • Перекомпилируйте/исправьте сборку и добавьте атрибут InternalsVisibleToAttribute