2008-09-30 3 views
15

나를 해고하기 전에이 일을하려고하지 않고 있지만 another post의 누군가가 가능하다고 말했습니다. 그게 어떻게 가능해? 리플렉션을 사용하여 상속받은 것을 들어 본 적이 없습니다. 그러나 나는 ... 이상한 일을 본 적이.NET에서 리플렉션을 사용하여 봉인 된 클래스에서 상속하는 방법은 무엇입니까?

+1

Mmhh를 사용할 수있는 대신에 기지 정상적인 System.Collections.Generic.KeyValuePair를 사용하지만 것 간단한 implentation 예 내가 여기 생각입니다. 그 질문에 대답 한 사람에게는 19 명의 대표자가 있습니다 (30 부 기준). 그는 그가 말하는 것에 대해 알지 못합니다.다른 한편으로 우리는 당신이 그것을 가질 수 없다고 말합니다. 따라서이 경우 자신을 신뢰해야합니다. – OscarRyz

+0

:) Kilhoffer (2,459) 대 dalle.myopenid.com (19) – OscarRyz

+0

웃기는 소리, 오스카! – user18931

답변

13

오버라이드 할 가상 함수가 없으면 봉인 된 클래스를 서브 클래 싱하는 것이 그리 중요하지 않습니다.

당신은, 당신은 다음과 같은 컴파일러 오류 얻을 거기에 가상 함수와 함께 봉인 된 클래스를 작성하려고하면 : 당신이 기본 클래스에서 그들을 선언에 의해 밀봉 클래스에 가상 함수를 얻을 수 있습니다, 그러나

// 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를 사용해 보았습니다. (루비는 모든 hackety 언어의 해킹입니다.

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

+1

나는 누군가가 clr 자체를 패치 예제를 보았다. Dinis Cruz와 OWASP에 대한 검색을 수행하면 – alexmac

+1

crikey가됩니다. 그건 하드 코어 –

+8

공격자가 보안 시스템보다 강한 보안 결함은 결함이 아닙니다. "모든 잠금 장치를 휴대 전화의 Bluetooth 명령에 응답한다는 점을 제외하고는 모든 잠금 장치를 동일한 것으로 교체하여 건물에 침입했습니다." 블루투스 공격은 내 잠금 장치를 제거한 것과 비교할 때 무의미합니다! –

1

그것은 MIGHT (내가 할 수있는 경우 크기를 증가시킬 것입니다). freenode에 따르면, Reflection.Emit을 사용하여 바이트 코드를 수정하고 JIT에게 새로운 바이트 코드 세트를 넘겨 주어야합니다.

아니요. KNOW ... 어떻게 생각 했나요?

+0

그것이 의미가있는 유일한 방법입니다. 관련된 일에 대해, 어떻게 도대체 누가 그것을 정당화 할 수 있 었는가 ?? 그냥 미쳤어. – Kilhoffer

+1

정당하게 정당화 할 수 없습니다. – MagicKat

+1

그렇게하면 봉인 된 클래스에서 실제로 파생되지는 않을 것입니다 ... 봉인을 제거하기 위해 수업에 빠져있을 것입니다. 그런 다음 정상적으로 파생됩니다. 그건 당신의 문제에 대한 유효한 해결책이 될 수 있습니다,하지만 난 그냥 봉쇄 클래스에서 파생되지 않아 더 이상 :-) –

1

다른 포스터는 더 일반적인 읽기 전용 반사 API가 아닌 Reflection.Emit의 줄을 따라 생각해 왔습니다.

그러나 여전히 (적어도 this article에 따르면) 불가능합니다. 그러나 방출 된 코드를 실제로 실행하려고 시도 할 때까지는 갇혀 있지 않은 Reflection.Emit을 사용하여 어떤 것을 망칠 수도 있습니다.

8

다른 스레드에서 잘못된 가정을 게시하여 죄송합니다. 올바르게 회신하지 못했습니다. Reflection.Emit을 사용하는 다음 예제를 사용하면 다른 클래스에서 파생되는 방법을 보여 주지만 런타임에 TypeLoadException을 throw하는 데 실패합니다. 에

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(); 
    } 
} 
+2

생성 한 것을로드 할 수 없다면 파생 클래스를 만드는 것으로 생각하지 않습니다 ... 결국, 'Reflection.Emit'을 사용하여 모든 종류의 엉망진창을 만들 수 있지만, 그런 것들이 어떻게 든 이제는 유효하게 만들지 않습니다. –

+4

@OrionEdwards : 이것이 내가이 답변에 쓴 것입니다. 그것은 작동하지 않을 것이며 이전의 가정에서 틀 렸습니다. – dalle

-2

그것을

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

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

넣어이 GenericKeyValueBase라는 새로운 클래스를 만들고 해당 상속 플러스 추가를위한 추가 확장 메서드를 추가 할 수 있습니다/제거 (AddAt 및 RemoveAt을) 당신의 정말 멋지다면 새로운 파생 클래스 (콜렉션/사전으로 만드십시오). 명성 유용 때

위의 코드를

class GenericCookieItem<TCookieKey, TCookieValue> : GenericKeyValueBase<TCookieKey,TCookieValue> 
    { 
     public GenericCookieItem(TCookieKey KeyValue, TCookieValue ItemValue) : base(KeyValue, ItemValue) 
     { 
     } 
    } 
+0

이것이 봉인 된 클래스에서 상속하는 방법과 관련이 없음을 알 수 없습니다. – Abel

+0

위의 내용을 구현 한 봉인 된 클래스는 의사 확장 성을 위해 TCookieKey/Value 개체를 사용하여 기능을 향상시킬 수 있습니다. 이 메서드는 기본 클래스에서 숨길 수도 있습니다 ... – Jay

관련 문제