如何通过引用的字段/属性访问属性

时间:2012-12-06 14:03:29

标签: c# reflection

我想知道是否有可能创建一个方法,只需将属性/字段的名称传递给set,即通过反射更新属性/字段,即

IFTDGN.Set( "S009", "E1001", "B" );

其中S009IFTDGN类中包含的字段,E1001是通过S009字段访问的字段/属性,最后是B是我想要放入E1001属性/字段的值。

我有这段代码(为了便于复制):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EDIDemo
{
    using System.Reflection;

    class Program
    {
        static void Main( string[] args )
        {
            IFTDGN iftdgn = new IFTDGN();
            iftdgn.S009.E1001.Set( "A" );
            iftdgn.S009.E1002.Set( "CC" );

            iftdgn.Set( "S009", "E1001", "B" );

            Console.WriteLine( iftdgn.CreateMessage() );
            Console.ReadKey();
        }
    }

    /// <summary>
    ///  Represents an International Forwarding and Transport Dangerous Goods Notification message 
    /// </summary>
    class IFTDGN : EDIMessage
    {
        public S009 S009 = new S009();

        public IFTDGN()
            : base()
        {
            base.RegisterMessage( this.GetType().Name );
        }

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

            sb.AppendLine( "S009" );
            sb.AppendFormat( "\t{0} {1}\n", "E1001", S009.E1001.Code.Tag );
            sb.AppendFormat( "\t{0} {1}\n", "E1002", S009.E1002.Code.Tag );

            return sb.ToString();
        }

        public override void Set( string segment, string element, string code )
        {
            // *** THIS IS THE BIT I AM HAVING TROUBLE WITH **
            var fi_seg = this.GetType().GetFields().FirstOrDefault( p => p.Name == segment );
            var pi_elem = fi_seg.GetType().GetProperties().FirstOrDefault( p => p.Name == element );
        }

    }

    class S009
    {
        protected IDictionary<String, EDIDataElement> Elements = new Dictionary<String, EDIDataElement>()
        {
            { "E1001", new E1001() },
            { "E1002", new E1002() }
        };

        public E1001 E1001 { get { return (E1001)Elements[ "E1001" ]; } }
        public E1002 E1002 { get { return (E1002)Elements[ "E1002" ]; } }
    }

    abstract class EDIMessage
    {
        protected String MessageID;

        protected EDIMessage()
        { }

        protected void RegisterMessage( String messageID )
        {
            this.MessageID = messageID;
        }

        public virtual void Set( String segment, String element, String code )
        {
            throw new NotImplementedException();
        }

        public abstract String CreateMessage();

    }

    abstract class EDIDataElement
    {
        public Code Code { get; private set; }

        public virtual bool Mandatory
        {
            get
            {
                return false;
            }
        }

        protected IList<Code> Codes = new List<Code>();
        protected String ElementID;

        public virtual void Set( String code )
        {
            if ( !Codes.Any( c => c.Tag == code ) )
                throw new Exception( "Code '" + code + "' not found for element '" + ElementID + "'" );

            this.Code = Codes.FirstOrDefault( c => c.Tag == code );
        }

        protected void RegisterElement( String elementID )
        {
            this.ElementID = elementID;
        }

    }

    class E1001 : EDIDataElement
    {
        public E1001()
            : base()
        {
            base.Codes.Add( new Code( "A", "Code A" ) );
            base.Codes.Add( new Code( "B", "Code B" ) );
            base.Codes.Add( new Code( "C", "Code C" ) );
            base.Codes.Add( new Code( "D", "Code D" ) );
            base.Codes.Add( new Code( "E", "Code E" ) );

            base.RegisterElement( this.GetType().Name );
        }

        public override void Set( String code )
        {
            base.Set( code );
        }

        public override bool Mandatory
        {
            get
            {
                return true;
            }
        }

    }

    class E1002 : EDIDataElement
    {
        public E1002()
            : base()
        {
            base.Codes.Add( new Code( "AA", "Code AA" ) );
            base.Codes.Add( new Code( "BB", "Code BB" ) );
            base.Codes.Add( new Code( "CC", "Code CC" ) );
            base.Codes.Add( new Code( "DD", "Code DD" ) );
            base.Codes.Add( new Code( "EE", "Code EE" ) );

            base.RegisterElement( this.GetType().Name );

        }

        public override void Set( String code )
        {
            base.Set( code );
        }

        public override bool Mandatory
        {
            get
            {
                return true;
            }
        }

    }

    class Code
    {
        public string Tag { get; protected set; }
        public string Name { get; protected set; }

        public Code( string tag, string name )
        {
            Tag = tag;
            Name = name;
        }
    }

}

基本上,我希望pi_elem变量包含引用PropertyInfo属性/字段的FieldInfoE1001,但它始终返回null

1 个答案:

答案 0 :(得分:1)

我想

 var pi_elem = fi_seg.GetType().GetProperties().FirstOrDefault( p => p.Name == element );

可能是:

 var pi_elem = fi_seg.FieldType.GetProperties().FirstOrDefault( p => p.Name == element );