2009-09-22 4 views
3

최근 C#에서 제네릭 클래스를 참조하는 것과 관련된 많은 코드 냄새를 발견했습니다. 내 불만은 특히 DependencyObject를 상속하고 DependencyProperties를 포함하는 클래스에 적용됩니다.유형을 스스로 참조하는 더 좋은 방법이 있습니까?

기본 문제는 종속성 속성을 선언 할 때 일반적으로 소유자이라고도하는 현재 형식을 참조한다는 것입니다. 이것은 잘 작동하고 일반적으로 개체가 여러 종속성 속성을 포함하고 유형 이름을 여러 위치에 다시 집어 넣어야하는 경우를 제외하고는 단순한 일반이 아닌 객체에 대해서는별로 문제가되지 않습니다. 비주얼 스튜디오).

public class MyDependencyObject : DependencyObject 
{ 
    public int MyProperty 
    { 
     get { return (int)GetValue(MyPropertyProperty); } 
     set { SetValue(MyPropertyProperty, value); } 
    } 

    public static readonly DependencyProperty MyPropertyProperty = 
     DependencyProperty.Register("MyProperty", typeof(int), typeof(MyDependencyObject), new UIPropertyMetadata(0)); 
} 

은 내가 최근에 불구하고 찾아 봤는데 제네릭의 광범위한 사용과이 burdonsome 명시 적 자기 참조 연습을 결합 할 때 코드가 정말 추한되기 시작한다는 것입니다.

public class MyDependencyObject<TypeA, TypeB, TypeC, TypeD> : DependencyObject 
{ 
    public int MyProperty1 
    { 
     get { return (int)GetValue(MyPropertyProperty1); } 
     set { SetValue(MyPropertyProperty1, value); } 
    } 

    public static readonly DependencyProperty MyPropertyProperty1 = 
     DependencyProperty.Register("MyProperty1", typeof(int), typeof(MyDependencyObject<TypeA, TypeB, TypeC, TypeD>)); 

    public int MyProperty2 
    { 
     get { return (int)GetValue(MyPropertyProperty2); } 
     set { SetValue(MyPropertyProperty2, value); } 
    } 

    public static readonly DependencyProperty MyPropertyProperty2 = 
     DependencyProperty.Register("MyProperty2", typeof(int), typeof(MyDependencyObject<TypeA, TypeB, TypeC, TypeD>)); 

    public int MyProperty3 
    { 
     get { return (int)GetValue(MyPropertyProperty3); } 
     set { SetValue(MyPropertyProperty3, value); } 
    } 

    public static readonly DependencyProperty MyPropertyProperty3 = 
     DependencyProperty.Register("MyProperty3", typeof(int), typeof(MyDependencyObject<TypeA, TypeB, TypeC, TypeD>)); 

    public int MyProperty4 
    { 
     get { return (int)GetValue(MyPropertyProperty4); } 
     set { SetValue(MyPropertyProperty4, value); } 
    } 

    public static readonly DependencyProperty MyPropertyProperty4 = 
     DependencyProperty.Register("MyProperty4", typeof(int), typeof(MyDependencyObject<TypeA, TypeB, TypeC, TypeD>)); 
} 

내 질문 사람은 위의 그림과 같이 일반적인 매개 변수를 사용하여 전체 유형 이름 상황에서 참조 할 필요가 횟수를 줄이는 어떤 트릭, 해킹, 또는 정당한 솔루션의 인식 여부입니다.

전체 공개 : Microsoft .Connect 사이트에서이 문제를 제기했지만 self referencing keyword 아이디어를 거부했지만 해결 방법이나 대체 솔루션을 제공하지 않았습니다. 내 아이디어는 소유자, OwnerClass 또는 ThisType과 같은 키워드를 사용하여 키워드가 사용되는 유형을 일반적으로 나타 내기위한 것입니다.

답변

3

고통을 덜어주기 위해 할 수있는 몇 가지 방법이 있습니다. 현재 클래스의 형식 정보가 들어있는 정적 변수를 만듭니다.

private static readonly Type ThisType = typeof(MyDependencyObject<TypeA, TypeB, TypeC, TypeD>)); 

public int MyProperty1 
{ 
    get { return (int)GetValue(MyPropertyProperty1); } 
    set { SetValue(MyPropertyProperty1, value); } 
} 

public static readonly DependencyProperty MyPropertyProperty1 = 
    DependencyProperty.Register("MyProperty1", typeof(int), ThisType); 

다음 당신은 당신의 게터에 대한 참조를 만들기 위해 this 영리한 트릭을 사용할 수 있고 호텔은 안전 리팩토링.

private static string GetPropertyName<TSource, TResult>(Expression<Func<TSource, TResult>> expression) 
{ 
    if (expression.NodeType == ExpressionType.Lambda && expression.BodyType == ExpressionType.MemberAccess) 
    { 
    PropertyInfo pi = (expression.Body as MemberExpression).Member as PropertyInfo; 
    if (pi != null) 
    { 
     return pi.Name; 
    } 
    } 
    throw new ArgumentException("expression", "Not a property expression."); 
} 

이제 코드에서 이렇게됩니다.

private static readonly Type ThisType = typeof(MyDependencyObject<TypeA, TypeB, TypeC, TypeD>)); 

public int MyProperty1 
{ 
    get { return (int)GetValue(MyPropertyProperty1); } 
    set { SetValue(MyPropertyProperty1, value); } 
} 

public static readonly DependencyProperty MyPropertyProperty1 = 
    DependencyProperty.Register(GetPropertyName((MyDependencyObject x) => x.MyProperty1), typeof(int), ThisType); 
+0

정적 변수를 사용하는 것이 좋습니다. 그러나 여전히 두 가지 문제가 있습니다. 1. 모든 클래스 또는 적어도 일부 기본 클래스에서 상속 한 클래스에 정적 멤버를 공백으로 적용 할 수 없으므로 필자가 작성한 각 DependencyObject에 대해 이와 같은 변수를 작성해야합니다. 2. 다른 메서드 또는 형식 선언에 대한 제네릭 매개 변수로 형식을 참조해야 할 때 또 다른 문제가 있습니다. 모두 당신의 솔루션은 정적 변수를 생성하는 데 최소한의 코드가 필요하며 꽤 유연한 이름 지정의 유연성을 허용한다고 생각합니다. – jpierson

관련 문제