2017-04-19 1 views
1

부모 개체 또는 사용자 개체의 사용자 지정 특성에 액세스하려면 어떻게해야합니까? SQLFieldInfo 구조체의 FieldInfo 속성을 살펴보십시오.C# 소유자 개체의 사용자 지정 특성 액세스

여기 내가 필요한 것을 보여주고 컴파일 할 더 자세한 프로그램이 있습니다.

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 

     Employee myclass = new Employee(); 

     // Load from sql server... 
     myclass.Name = "Alain"; 
     myclass.Age = 51; 
     //---- 

     MessageBox.Show(myclass.Name.ToString()); // Should return Alain 
     MessageBox.Show(myclass.Age.FieldInfo.Type.ToString()); // Should output "int" 
    } 
} 

// This next class is generated by a helper exe that reads SQL table design and create the class from it 
[SQLTableAttribute(DatabaseName = "Employees", Schema = "dbo", TableName = "Employees")] 
public class Employee 
{ 
    [SQLFieldAttribute(FieldName = "ID", Type = SqlDbType.Int)] 
    public SQLFieldInfo<int> ID { get; set; } 

    [SQLFieldAttribute(FieldName = "Name", Type = SqlDbType.NVarChar, Size = 200)] 
    public SQLFieldInfo<String> Name { get; set; } 

    [SQLFieldAttribute(FieldName = "Age", Type = SqlDbType.Int)] 
    public SQLFieldInfo<int> Age { get; set; } 
} 


public struct SQLFieldInfo<T> 
{ 

    private readonly T value; 

    public SQLFieldInfo(T Value) 
    { 
     this.value = Value; 
    } 


    public static implicit operator SQLFieldInfo<T>(T Value) 
    { 
     return new SQLFieldInfo<T>(Value); 
    } 


    public T Value 
    { 
     get 
     { 
      return this.value; 
     } 
    } 


    public override string ToString() 
    { 
     return this.value.ToString(); 
    } 


    public SQLFieldAttribute FieldInfo 
    { 
     get 
     { 
      // Need to retreive the attribute class of the parent or declaring member 

      return null; 
     } 
    } 
} 

// Holds the sql field information 
public class SQLFieldAttribute : Attribute 
{ 
    public string FieldName { get; set; } 
    public SqlDbType Type { get; set; } 
    public bool AllowNull { get; set; } 
    public int Size { get; set; } 
} 

// Holds the sql table information 
public class SQLTableAttribute : Attribute 
{ 
    public string DatabaseName { get; set; } 
    public string Schema { get; set; } = "dbo"; 
    public string TableName { get; set; } 
} 

감사합니다!

알랭

+0

'B'는'A '안에 어떻게 포함되어 있는지 어떻게 알아야합니까? 나는'B.myprop2' 내부의 호출 스택을 검사하여'A.myprop'가 이전 프레임인지 여부를 확인할 수 있다고 생각합니다. 그러나 호출 스택의 레이아웃 종속성을 취하는 것이 문제를 요구합니다. 특히 릴리스 빌드에서 다른 레이아웃을 가질 수 있습니다. –

+0

B가 그것에 대해 알기를 기대하지는 않지만 CLR 예에서 시스템이 작성자 인스턴스를 알고 리플렉션을 사용하여 사용자 정의 속성에 액세스하는 것이 쉬워야한다고 생각합니다. – user1603581

답변

1

첫째, MSDN은 당신의 친구입니다. (A 위에서 상당히 번역해야한다)

var attribute = typeof(A).GetProperty("myprop").GetCustomAttributes(true) 
         .OfType<MycustomAttrib>().FirstOrDefault(); 
+0

Arsen에게 감사드립니다. 그러나 호출자 클래스와 소품 이름을 모르는 경우 클래스 B는 제네릭 클래스이며 어디에서나 선언 될 수 있습니다. – user1603581

+0

A에 대해 알고있는 점은 무엇입니까? 그것은 generic argument로서 B에 건네지는 타입인가? –

+0

그 시점에서 A에 대해 아무것도 알지 못합니다. 클래스 X의 클래스 B를 기반으로하는 멤버의 사용자 지정 특성 (있는 경우)이 필요합니다. – user1603581

1

내 데이터 클래스는 다음과 같습니다 당신이 조상의 속성을 얻으려면

그리고, 단지 방법의 상속 플래그 true를 지정 :

public class Foo 
{ 
    [Argument(Help = "Name", AssignmentDelimiter = "=")] 
    public string Name 
    { 
     get; 
     set; 
    } 
} 

도우미 클래스는 객체의 속성 값을 읽는 책임 :

(3210)는 단순히,이 기능을 사용하려면

string delimiter = GetCommandLineDelimiter(() => myObject.Name); 

속성 이름, 즉 "="에 AssignmentDelimiter의 속성 값을 얻을 것이다.

0

이것은 작동합니다. 모든 속성을보고 리플렉션을 사용하여 사용자 지정 특성에 대한 참조를 게으른 초기화하고 있습니다.

public class MycustomAttribAttribute : Attribute 
{ 
    public MycustomAttribAttribute(string name) 
    { 
     this.Name=name; 
    } 
    public string Name { get; private set; } 
} 
class A 
{ 
    public A() { MyProp=new B(); } 
    [MycustomAttrib(name: "OK")] 
    public B MyProp { get; set; } 
} 


class B 
{ 
    private static Lazy<MycustomAttribAttribute> att = new Lazy<MycustomAttribAttribute>(() => 
    { 
     var types = System.Reflection.Assembly.GetExecutingAssembly().DefinedTypes; 

     foreach(var item in types) 
     { 
      foreach(var prop in item.DeclaredProperties) 
      { 
       var attr = prop.GetCustomAttributes(typeof(MycustomAttribAttribute), false); 
       if(attr.Length>0) 
       { 
        return attr[0] as MycustomAttribAttribute; 
       } 
      } 
     } 
     return null; 
    }); 
    public string MyProp2 
    { 
     get 
     { 
      return att.Value.Name; 
     } 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     // Finds the attribute reference and returns "OK" 
     string name = (new A()).MyProp.MyProp2; 
     // Uses the stored attribute reference to return "OK" 
     string name2 = (new A()).MyProp.MyProp2; 
    } 
} 
+0

감사합니다. ja72, 클래스에 추가하면 어떻게됩니까? 두 번째 속성 인 MyProp2는 작성한 코드에서 항상 첫 번째로 선언 된 속성의 사용자 지정 특성을 반환합니다. 진짜 질문은 우리가 발신자 소품을 알 필요가 있다는 것입니다. { public A() {MyProp = new B(); } [MycustomAttrib (이름 : "OK")] public B MyProp {get; 세트; } [MycustomAttrib (name : "OK2")] public B MyProp2 {get; 세트; } } – user1603581

+0

추가 정보로 질문을 편집하여 정확히 무엇을 묻고 있는지 확인하십시오. _ 거의 대부분 컴파일하는 최소한의 검증 가능한 예제를 제공하십시오. – ja72

+0

내 질문 JA72 업데이트했습니다 :) – user1603581

관련 문제