【发布时间】:2012-12-06 14:03:28
【问题描述】:
我想知道是否可以创建一个方法,通过反射来更新属性/字段,只需传入要设置的属性/字段的名称,即
IFTDGN.Set( "S009", "E1001", "B" );
其中S009 是包含在IFTDGN 类中的字段,E1001 是通过S009 字段访问的字段/属性,最后B 是我要放入@ 的值987654328@属性/字段。
我有这段代码(以便于重现):
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 变量包含E1001 引用的属性/字段的PropertyInfo 或FieldInfo,但它总是返回null。
【问题讨论】:
-
那是在原始类中寻找属性。我正在考虑访问另一个级别的属性和字段。
-
还是一样的,只是先获取第一种类型的属性,然后再对生成的对象进行设置。
-
@poke: 如果
fi_seg给了我S009字段的FieldInfo对象,那么'pi_elem' 在尝试获取封闭的'E1001' 的PropertyInfo时如何返回null财产? -
我猜 fi_seg 是 FieldInfo 类型,它没有任何“E1001”属性。你应该看看目标类型。
标签: c# reflection