문제

나는 System.Attribute 클래스를 사용하는 것이 좋은 생각으로 보였던 상황에 빠졌습니다.

응용 프로그램에 인쇄 할 객체가 있으며 각 속성 앞에 레이블이 필요합니다 (또는 그 이전의 문자열). 각 속성을 하드 코딩 할 수 있습니다.

Console.WriteLine("Color:"+obj.color);
Console.WriteLine("Size:"+obj.size);

그리고 각 속성에 대해. 그러나 대신 에이 '레이블'을 하드 코딩 할 필요가없는 코드를 만들려고 했으므로 모든 속성을 동적으로 인쇄 할 수있었습니다.

System.Attribute 클래스를 사용하여 그런 것을 얻었습니다.

public class MyObject 
{
    [MyCustomLabel("Color:")]
    public string Color;

    [MyCustomLabel("Size:")]
    public string Size;
    //etc...
}

그래서 여기에 내 문제가 온다 :이 속성의 가치를 검색하는 것은 불가능하지는 않지만, 반사를 사용해야했기 때문에 친근하지 않다.

나는 반사를 사용하는 것을 두려워하지는 않지만, 그것이 만들어지지 않은 것에 대한 속성을 사용하고있는 것처럼 보였다.

나는 속성을 사용하기에 가장 좋은 장소는 어디에 있는지 궁금하며, 이것이 실제로 그것을 사용하기위한 상황인지 궁금합니다.

도움이 되었습니까?

해결책

속성과 반사는 함께 진행됩니다. 일부 컴파일러/런타임 속성을 제외하고는 코드를 반영하여 사용할 수있는 방법이 없습니다.

즉, 귀하의 접근 방식은 합리적이며 속성을보고 싶을 수도 있습니다. System.ComponentModel 유용한 메타 데이터로 속성을 장식하기위한 여러 클래스가있는 네임 스페이스.

다른 팁

당신은 올바른 길을 가고 있습니다.

또한이 목적을 위해 이미 맞춤형으로 만들어진 [displayName] 속성이 있으며, 2.0 이후 .NET에 있습니다.

http://msdn.microsoft.com/en-us/library/system.componentmodel.displaynameattribute.aspx

콘솔에 글을 쓰는 경우 디버깅 스타일 출력입니다. 원하는 것은 오타/복사 페이스트 오류 가능성을 최소화합니다.

이것은 후드 아래에서 혼란 스럽지만 통화 사이트에서 매우 효과적입니다.

public static void WriteNameAndValue<T,TValue>(
    this TextWriter tw, T t,
    Expression<Func<T, TValue>> getter)
{
    var memberExpression = getter.Body as MemberExpression;
    if (memberExpression == null)
        throw new ArgumentException("missing body!");
    var member = memberExpression.Member;
    tw.Write(member.Name);
    tw.Write(": ");
    if (member is FieldInfo)
    {
        tw.Write(((FieldInfo)member).GetValue(t));
    }
    else if (member is PropertyInfo)
    {
        tw.Write(((PropertyInfo)member).GetValue(t, null));
    }
}


public static void WriteNameAndValueLine<T,TValue>(
    this TextWriter tw, T t,
    Expression<Func<T, TValue>> getter)
{

    WriteNameAndValue<T,TValue>(tw, t, getter);
    tw.WriteLine();
}

그런 다음 글을 쓸 수 있습니다

t.Foo = "bar";
t.Bar = 32.5;
Console.Out.WriteNameAndValueLine(t, x => x.Foo);
Console.Out.WriteNameAndValueLine(t, x => x.Bar);
// output
// Foo: bar
// Bar: 32.5

리소스를 통해 런타임과 현지화를 고려할 때이를 더 구성 할 수 있으려면 그렇게 할 수 있지만 그렇게 할 수 있지만 다른 표준화 된 접근 방식을 고려할 것입니다.

추신 : 공상을 원한다면 FieldInfo/PropertyInfo 스위치를 대체 할 수 있습니다.

tw.Write(getter.Compile()(t));

그런 다음 표현식에서 MethodInfo를 확인할 수 있습니다 (또는 임의의 람다를 허용하고 줄 번호 나 다른 일반 텍스트 만 삽입합니다.이 경로를 내려 가지 않겠다고 제안하면 이미 혼동하지 않는 것이 좋습니다. 간단한 벌목 방법이어야합니다.

이것이 바로 직렬화가 작동하는 방식이므로 귀하의 접근 방식이 합리적이라고 말할 것입니다. 당신이 접근 할 수있는 또 다른 방법은 속성 이름과 타이틀의 사전을 만들고 속성 이름을 기반으로 제목을 찾는 것입니다.

응용 프로그램에 인쇄 할 객체가 있으며 각 속성 앞에 레이블이 필요합니다 (또는 그 이전의 문자열).

귀하의 경우에 속성을 사용한다고 생각하는 이유는 무엇입니까? 응용 프로그램 에서이 개체를 어디에 인쇄합니까?

어쩌면 그냥 구현할 수도 있습니다 토스트 링 당신의 대상에서
예를 들어

public override string ToString()
{
    StringBuilder sb = new StringBuilder();

    sb.Append("PropertyX: ");
    sb.AppendLine(this.PropertyX);

    // get string from resource file
    sb.Append(Resources.FileName);
    sb.Append(": ");
    sb.AppendLine(this.FileName);

    sb.Append("Number: ");
    sb.AppendLine(this.Number.ToString());

    return sb.ToString();
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top