通过自定义属性反映时出错
我试图根据类的某些字段的名称和通过反射存在的自定义属性来获取类的某些字段的值。 我的自定义属性是:
[AttributeUsage (AttributeTargets.All, AllowMultiple=true)]
public sealed class ColumnAttribute : Attribute
{
internal string name = "";
internal string length = "";
internal string precision = "";
public ColumnAttribute() { }
public ColumnAttribute(String name) { this.name = name; }
public ColumnAttribute(String name, String length) { }
public ColumnAttribute(String name, String length, String precision) { }
public String Name { get { return name; } set { name = value; } }
public String Length { get { return length; } set { length = value; } }
public String Precision { get { return precision; } set { precision = value; } }
}
使用此属性的示例类是:
class SampleEntity
{
//private int number;
public string name;
//float marks;
public virtual int Number { get; set; }
public SampleEntity() { }
public SampleEntity(int number)
{
this.Number = number;
}
public void conversation(string request, string response) { }
public void ordinary() {
Console.Write("This isn't ordinary...");
}
[ColumnAttribute (Name = "XWBCCD")]
public String XWBCCD { get; set; }
[ColumnAttribute (Name = "XWBNCD")]
public String XWBNCD { get; set; }
我还有一个具有不同字段名称的不同类:
class SampleRepository
{
[ColumnAttribute(Name = "XWBCCD")]
public String SomeOtherFieldName { get; set; }
[ColumnAttribute(Name = "XWBNCD")]
public String XWBNCD { get; set; }
[ColumnAttribute(Name = "XWBWCD")]
public String XWBWCD { get; set; }
}
通过反射,我尝试通过匹配属性“名称”参数而不是字段名称来复制值。 问题是,在反射期间,这种比较不会通过传递字段的 getCustomAttributes() 方法进行。 我解决这个问题的方法(到目前为止失败)是: 首先,我传递 2 个对象,objSrc(第一类,已填充)和 objDesc(第二类,空)
FieldInfo[] srcFields = objSrc.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.IgnoreCase |BindingFlags.FlattenHierarchy);
FieldInfo[] destFields = objDest.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);
然后我尝试迭代地对所有字段执行反射
foreach (FieldInfo srcFld in srcFields)
{
foreach (FieldInfo destFld in destFields)
{
if (((MemberInfo)srcFld).Name.Equals(((MemberInfo)destFld).Name)){
destFld.SetValue(objDest, srcFld.GetValue(objSrc));
break;
}
object[] srcAttr = srcFld.GetCustomAttributes(true);
object[] destAttr = destFld.GetCustomAttributes(true);
if (Utils.Length(srcAttr) == 1 && Utils.Length(destAttr) == 1){
if ((srcAttr[0]).Equals(destAttr[0]) && srcFld.FieldType.Equals(destFld.FieldType))
destFld.SetValue(objDest, srcFld.GetValue(objSrc));
else
break;
}
}
}
GetCustomAttributes() 方法出现问题,因为它返回 null 。
I am trying to fetch the values of certain fields of a class based on their names and the presence of a customized attribute through reflection.
My Custom attribute is :
[AttributeUsage (AttributeTargets.All, AllowMultiple=true)]
public sealed class ColumnAttribute : Attribute
{
internal string name = "";
internal string length = "";
internal string precision = "";
public ColumnAttribute() { }
public ColumnAttribute(String name) { this.name = name; }
public ColumnAttribute(String name, String length) { }
public ColumnAttribute(String name, String length, String precision) { }
public String Name { get { return name; } set { name = value; } }
public String Length { get { return length; } set { length = value; } }
public String Precision { get { return precision; } set { precision = value; } }
}
A sample class that uses this is :
class SampleEntity
{
//private int number;
public string name;
//float marks;
public virtual int Number { get; set; }
public SampleEntity() { }
public SampleEntity(int number)
{
this.Number = number;
}
public void conversation(string request, string response) { }
public void ordinary() {
Console.Write("This isn't ordinary...");
}
[ColumnAttribute (Name = "XWBCCD")]
public String XWBCCD { get; set; }
[ColumnAttribute (Name = "XWBNCD")]
public String XWBNCD { get; set; }
I am also having a different class that's having different field names :
class SampleRepository
{
[ColumnAttribute(Name = "XWBCCD")]
public String SomeOtherFieldName { get; set; }
[ColumnAttribute(Name = "XWBNCD")]
public String XWBNCD { get; set; }
[ColumnAttribute(Name = "XWBWCD")]
public String XWBWCD { get; set; }
}
Through reflection, I am trying to copy values by matching the attribute 'name' parameter rather than the fieldname.
Trouble is, that during reflection, such comparison is not happening through getCustomAttributes() method passed over fields.
My approach to solve this problem (That's failing so far ) has been :
First I pass on 2 objects, objSrc (of first class, which is populated) and objDesc (of second class that's empty)
FieldInfo[] srcFields = objSrc.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.IgnoreCase |BindingFlags.FlattenHierarchy);
FieldInfo[] destFields = objDest.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);
Then I am trying to iteratively perform reflection over all fields
foreach (FieldInfo srcFld in srcFields)
{
foreach (FieldInfo destFld in destFields)
{
if (((MemberInfo)srcFld).Name.Equals(((MemberInfo)destFld).Name)){
destFld.SetValue(objDest, srcFld.GetValue(objSrc));
break;
}
object[] srcAttr = srcFld.GetCustomAttributes(true);
object[] destAttr = destFld.GetCustomAttributes(true);
if (Utils.Length(srcAttr) == 1 && Utils.Length(destAttr) == 1){
if ((srcAttr[0]).Equals(destAttr[0]) && srcFld.FieldType.Equals(destFld.FieldType))
destFld.SetValue(objDest, srcFld.GetValue(objSrc));
else
break;
}
}
}
Trouble happens on the GetCustomAttributes() method as it is returning null.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我为 vb.net 代码而不是 c# 表示歉意,但我碰巧有一个 linqpad 文件,我在其中做完全相同的事情,在这里:(
根本不是真正的生产就绪代码,但它让我明白了这个想法希望。)
I apologize for the vb.net code instead of c#, but I happen to have had a linqpad file where I was doing exactly the same thing, here ya go:
(Not really production ready code at all, but it gets the idea across I hope.)