Без виртуальных функций для переопределения нет большого количества точки в разделении на подклассы запечатанного класса.
, Если Вы пробуете, пишут запечатанный класс с виртуальной функцией в нем, Вы получаете следующую ошибку компилятора:
// error CS0549: 'Seal.GetName()' is a new virtual member in sealed class 'Seal'
Однако можно получить виртуальные функции в запечатанные классы путем объявления их в базовом классе (как это),
public abstract class Animal
{
private readonly string m_name;
public virtual string GetName() { return m_name; }
public Animal( string name )
{ m_name = name; }
}
public sealed class Seal : Animal
{
public Seal( string name ) : base(name) {}
}
, проблема все еще остается, хотя, я не вижу, как Вы могли красться мимо компилятора, чтобы позволить Вам объявить подкласс. Я пытался использовать IronRuby (рубин является hackiest всех hackety языков), но даже он не позволил бы мне.
'изолированная' часть встраивается в MSIL, таким образом, я предположил бы, что сам CLR на самом деле осуществляет это. Необходимо было бы загрузить код, демонтировать его, удалить 'изолированный' бит, затем повторно собрать его и загрузить новую версию.
Я сожалею о регистрации неправильных предположений в другом потоке, мне не удалось вспомнить правильно. Используя следующий пример, с помощью Отражения. Испустите, шоу, как произойти из другого класса, но он перестал работать во времени выполнения, бросающем TypeLoadException.
sealed class Sealed
{
public int x;
public int y;
}
class Program
{
static void Main(string[] args)
{
AppDomain ad = Thread.GetDomain();
AssemblyName an = new AssemblyName();
an.Name = "MyAssembly";
AssemblyBuilder ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
ModuleBuilder mb = ab.DefineDynamicModule("MyModule");
TypeBuilder tb = mb.DefineType("MyType", TypeAttributes.Class, typeof(Sealed));
// Following throws TypeLoadException: Could not load type 'MyType' from
// assembly 'MyAssembly' because the parent type is sealed.
Type t = tb.CreateType();
}
}
Это МОГЛО БЫ (увеличит размер, если я мог). По словам парней на freenode, это было бы включенное изменение кода байта, с помощью Отражения. Испустите, и вручение JIT нового набора кода байта.
Не то, чтобы я ЗНАЮ , как... это было, что они думали.
Другой плакат, возможно, думал больше вроде Отражения. Испустите, а не более обычные API Reflection только для чтения.
Однако все еще не возможно (по крайней мере, согласно эта статья ). Но, конечно, возможно завинтить somethings с Отражением. Испустите, которые не захватываются, пока Вы не пытаетесь на самом деле выполнить испускаемый код.
Создайте новый класс с именем GenericKeyValueBase
, поместите его в него
public class GenericKeyValueBase<TKey,TValue>
{
public TKey Key;
public TValue Value;
public GenericKeyValueBase(TKey ItemKey, TValue ItemValue)
{
Key = ItemKey;
Value = ItemValue;
}
}
И унаследуйте от него, плюс вы можете добавить дополнительные методы расширения для добавления / удаления (AddAt и RemoveAt) в ваш новый производный class (и сделайте его коллекцией / словарем), если вы чувствуете себя действительно круто.
Простой пример реализации, в котором вы могли бы использовать обычный System.Collections.Generic.KeyValuePair в качестве основы, но вместо этого можете использовать приведенный выше код
class GenericCookieItem<TCookieKey, TCookieValue> : GenericKeyValueBase<TCookieKey,TCookieValue>
{
public GenericCookieItem(TCookieKey KeyValue, TCookieValue ItemValue) : base(KeyValue, ItemValue)
{
}
}