문제

사용자 정의 속성을 사용하여 클래스 멤버가 양식 게시물 (지불 게이트웨이)으로 게시하기 위해 속성에 매핑되는 방법을 정의하고 있습니다. 사용자 정의 속성이 잘 작동하고 "이름"으로 속성을 얻을 수 있지만 멤버 자체가 속성을 얻고 싶습니다.

예를 들어:

getFieldName("name");

vs

getFieldName(obj.Name);

계획은 멤버와 함께 클래스를 우편 문자열로 직렬화하는 메소드를 작성하는 것입니다.

이 시점에서 내가 가지고있는 테스트 코드는 다음과 같습니다. 여기서 Ret는 문자열이고 속성 맵핑은 사용자 정의 속성입니다.

foreach (MemberInfo i in (typeof(CustomClass)).GetMember("Name"))
{
    foreach (object at in i.GetCustomAttributes(true))
    {
        PropertyMapping map = at as PropertyMapping;
        if (map != null)
        {
            ret += map.FieldName;
        }
    }
}

미리 감사드립니다!

도움이 되었습니까?

해결책

C# 3.0을 사용하지 않는 한 실제로는 이렇게 할 수 없습니다.

당신이하는 일은 컴파일러가 발현 트리를 생성 할 수 있도록 람다 표현식을위한 더미 방법을 생성한다는 것입니다 (컴파일러는 유형 검사를합니다). 그런 다음 그 나무를 파고 회원을 얻습니다. 그렇게 :

static FieldInfo GetField<TType, TMemberType>(
    Expression<Func<TType, TMemberType>> accessor)
{
    var member = accessor.Body as MemberExpression;
    if (member != null)
    {
        return member.Member as FieldInfo;
    }
    return null; // or throw exception...
}

다음 수업이 주어지면 :

class MyClass
{
    public int a;
}

다음과 같은 메타 데이터를 얻을 수 있습니다.

// get FieldInfo of member 'a' in class 'MyClass'
var f = GetField((MyClass c) => c.a); 

해당 필드를 참조하여 일반적인 방법으로 속성을 파헤칠 수 있습니다. 즉, 반사.

static TAttribute GetAttribute<TAttribute>( 
    this MemberInfo member ) where TAttribute: Attribute
{
    return member.GetCustomAttributes( typeof( TAttribute ), false )
        .Cast<TAttribute>().FirstOrDefault<TAttribute>();
}

이제 컴파일러가 크게 점령 한 내용으로 모든 필드에서 속성을 파낼 수 있습니다. 'A'비주얼 스튜디오를 바꾸면 리팩토링과 함께 작동합니다.

var attr = GetField((MyClass c) => c.a).GetAttribute<DisplayNameAttribute>();
Console.WriteLine(attr.DisplayName);

해당 코드에는 하나의 문자 그대로의 문자열이 없습니다.

다른 팁

절반을 조금 더 간단하게 할 수 있습니다.

    foreach (PropertyMapping attrib in
        Attribute.GetCustomAttributes(i, typeof(PropertyMapping)))
    {
        ret += map.FieldName; // whatever you want this to do...
    }

btw; 당신은 단어로 속성을 끝내는 습관을 가져야합니다. Attribute. 이로 인해 복제가 발생하더라도 (참조 [XmlAttributeAttribute]).

그러나 -RE 직렬화; 항상 사소한 것은 아닙니다. 기만적인 코드는 JSON.NET 등과 같은 직렬화 프레임 워크로 들어갑니다. 일반적인 접근 방식은 유형 컨버터를 얻는 것일 수 있지만 여러면에서 이것은 PropertyDescriptor:

    foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
    {
        Console.WriteLine("{0}={1}",
            prop.Name, prop.Converter.ConvertToInvariantString(
                prop.GetValue(obj)));
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top