2010-01-24 10 views
7

나는 이와 같은 추상 클래스를 가지고있다;정적, 일반적인 방법으로 현재 유형 가져 오기?

public abstract PropertyBase 
{ 
    public static System.Type GetMyType() 
    { 
     return !!!SOME MAGIC HERE!!! 
    } 
} 

저는 서브 클래 싱을하고 정적 GetMyType()을 호출 할 때 하위 클래스의 유형을 반환하고 싶습니다. 그래서 내가 하위 타입을 선언하면; 내가

var typeName = ConcreteProperty.GetMyType().Name; 

내가가 설정 될 '유형 이름을'기대 전화를 다음

public class ConcreteProperty: PropertyBase {} 

"ConcreteProperty." 나는 그것을 할 수있는 방법이 없다고 생각하지만 거기에있는 누군가가이 정보를 얻을 수있는 방법을 알고 있다면 나는 흥미 롭다.

(내가 해결하기 위해 노력하고있어 특히 문제는 WPF에서 종속성 속성의 상세이다

class NamedObject : DependencyObject 
{ 
    // declare a name property as a type, not an instance. 
    private class NameProperty : PropertyBase<string, NamedObject> { } 

    // call static methods on the class to read the property 
    public string Name 
    { 
     get { return NameProperty.Get(this); } 
     set { NameProperty.Set(this, value); } 
    } 
} 

내가 거의을 가지고, 나는 이런 식으로 뭔가를 할 수있을 싶어요 구현,하지만 확실히 내 NameProperty 클래스에서 필요한 정보를 얻을 수 없습니다)

+0

정적 인 이유는 무엇입니까? 가상 또는 추상으로 선언하면 문제가 발생할 수 있습니다. –

+0

왜 고정적입니까 : 이상한 각도이며 한 C#은 실제로 설계되지 않았습니다. 경우에 따라 유형에 하나의 값만있을 수 있습니다. 따라서 '클래스 Steve : Person {}'은 유형을 선언하지만 가능한 값이 하나뿐이기 때문에 'Steve'클래스는 인스턴스를 식별합니다. 'Steve'유형을 선언하면 싱글 톤 'Steve'가 선언됩니다. WPF DP는 다음과 같습니다. 인스턴스 데이터, 메타 데이터 또는 유형인지 여부를 결정할 수 없습니다. 모든 코드를 하나의 코드로 구성하려고합니다. 그것은 모두 투기 적 ATM입니다. 그러나 나는 그것을 추구하는 것에 관심이 있습니다. –

+0

다음과 같은 이유가 있습니다. 상용구 TypeDescriptor 코드의 부분 클래스 생성. 동적으로 생성 된 속성 이름은 형식에 정의 된 속성과 충돌 할 수 없으므로 형식 내에서 속성 이름 목록이 필요합니다. 이것은 더 많은 상용구 코드이므로 codegen에 포함됩니다. 그것도 변함이 없으므로 그것도 static을위한 완벽한 후보자입니다.그래서 정적 생성자 내에서 현재 유형의 속성을 포함하는 목록을 생성해야합니다. 글쎄, 지금은 T4 템플릿에서 마술 문자열을 사용해야합니다. – Will

답변

6

당신은 부분적으로 (달성 상속 깊이)를 사용하여 제네릭의 1 수준 수 있습니다.

class PropertyBase<T> 
{ 
    public static Type GetMyType() { return typeof (T); } 
} 

// the base class is actually a generic specialized by the derived class type 
class ConcreteProperty : PropertyBase<ConcreteProperty> { /* more code here */ } 

// t == typeof(ConcreteProperty) 
var t = ConcreteProperty.GetMyType(); 
+0

ConcreteProperty의 하위 클래스 인 경우 GetMyType의 ConcreteProperty를 계속 반환합니다. –

+0

사실입니다. 그리고이 접근법의 한계 중 하나. 하지만 여전히 OP의 의존성 속성 예제와 함께 도움이 될 수 있습니다. – LBushkin

+0

이것은 지금까지 내가 본 최선의 접근법이다. 유형에 대한 참조를 작성하여 유형 매개 변수에서 다시 인용하십시오. 예를 들어, 이것은 개발자에게 좀 더 많은 타이핑을 부과하지만 멋지게 작동합니다. 어쨌든, 이것은 아직 최고이며, 매우 도움이됩니다. 감사. –

4

정적 메서드가 형식에 연결되어 있으므로 하위 클래 싱 비트가 작동하지 않습니다. 형식의 메서드이며 인스턴스 메서드는 아닙니다. 하위 유형에는 기본 유형의 정적 메소드가 들어 있지 않습니다. 유형이 다르며 정적 메소드가 기본 유형에 연결되어 있기 때문입니다. 컴파일러가 파생 클래스를 통해 기본 클래스의 정적 메서드를 호출하도록 허용하더라도 실제로는 기본 클래스의 메서드를 호출합니다. 그것은 단지 구문 설탕입니다. 같은 이유로 서브 클래스에서 정적 메소드를 "오버라이드 (override)"할 수 없다.

0

왜 이런 식으로해야할까요? 메소드를 호출하면, 당신은 단순히뿐만 아니라이 작업을 수행 할 수있는 반면

var typeName = ConcreteProperty.GetMyType().Name; 

은 어쨌든 당신은

var typeName = typeof(ConcreteProperty).Name; 

이 작업을 수행 할 필요가 그냥 경우에, 당신은 대체 할 "그림자"를 사용할 수 있습니다 .. 유형을 알고 자식 클래스에서 기본 클래스의 구현.

public class ConcreteProperty : PropertyBase { 

     public new static Type GetMyType { 
      //provide a new implementation here 
     } 
    } 
+0

불행하게도 필자의 예제 코드에서는 필자가 필수적인 문제로 줄이기 위해 코드를 단순화했으며, 이는 사용자가 설명한 방식으로 해결할 수 있습니다. 하지만 내 솔루션에서 요구하는 것은 PropertyBase의 하위 클래스에 대해 '실제 유형이 무엇인가'를 묻는 것입니다. 예를 들어'this.GetType() '을 호출하는 방식은 항상 기본 유형이 아닌 실제 유형을 얻습니다. –