.NET에서 반사를 사용하여 밀봉 된 클래스에서 어떻게 상속받을 수 있습니까?

StackOverflow https://stackoverflow.com/questions/155087

  •  03-07-2019
  •  | 
  •  

문제

당신이 나에게 해고를 시작하기 전에, 나는 이것을하고 싶지 않지만 누군가가 다른 게시물 가능하다고 말했다. 그게 어떻게 가능해? 나는 반사를 사용하여 무엇이든 상속 된 것에 대해 들어 본 적이 없습니다. 하지만 나는 이상한 것들을 보았다 ...

도움이 되었습니까?

해결책

가상 함수가 재정의 할 수 없으면 밀봉 된 클래스를 서브 클래스하는 데는 별다른 점이 없습니다.

가상 함수가있는 밀봉 클래스를 쓰려고하면 다음 컴파일러 오류가 발생합니다.

// 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를 사용해 보았지만 (Ruby는 모든 Hackety 언어 중에서 가장 해킹된다) 심지어 나를 허락하지는 않을 것입니다.

'밀봉 된'부분이 MSIL에 포함되어 있으므로 CLR 자체가 실제로이를 시행한다고 생각합니다. 코드를로드하고 해부하고 '밀봉 된'비트를 제거한 다음 다시 조립 한 다음 새 버전을로드해야합니다.

다른 팁

다른 스레드에 잘못된 가정을 게시해서 죄송합니다. 올바르게 기억하지 못했습니다. 다음 예제를 사용하여 Reflection.emit을 사용하는 것은 다른 클래스에서 파생하는 방법을 보여 주지만 런타임이 타이핑을 던지는 경우 실패합니다.

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보다는 반사 선을 따라 더 많이 생각했을 수 있습니다.

그러나 여전히 가능하지 않습니다 (적어도에 따라 이 기사). 그러나 실제로 방출 된 코드를 실행하려고 할 때까지 갇히지 않은 반사와 함께 일치하지 않을 수 있습니다.

generickeyValuebase라는 새로운 클래스를 만듭니다

이것에 넣으십시오

  public class GenericKeyValueBase<TKey,TValue>
    {
        public TKey Key;
        public TValue Value;

        public GenericKeyValueBase(TKey ItemKey, TValue ItemValue)
        {
            Key = ItemKey;
            Value = ItemValue;
        }
    }

그리고 그 플러스에서 물려받은 새로운 파생 클래스에 추가/제거 (addat and removeat)를위한 추가 확장 방법을 추가 할 수 있으며 (정말 시원하게 느껴지는 경우 컬렉션/사전으로 만들 수 있습니다.

기본에 대해 일반 System.collections.generic.keyvaluepair를 사용하는 간단한 이식 예제. 그러나 위의 코드를 사용할 수 있습니다.

  class GenericCookieItem<TCookieKey, TCookieValue> : GenericKeyValueBase<TCookieKey,TCookieValue>
    {
        public GenericCookieItem(TCookieKey KeyValue, TCookieValue ItemValue) : base(KeyValue, ItemValue)
        {
        }
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top