我有一个扩展方法,我使用它尝试从对象中提取一些元数据,例如:
public static string ToTypeName(this object obj)
{
string name;
var asType = obj.GetType();
if (Attribute.IsDefined(asType, typeof(DataMemberAttribute)) || Attribute.IsDefined(asType, typeof(DataContractAttribute)))
{
var attrName = obj.GetType().GetCustomAttributes(typeof(DataContractAttribute), true).SingleOrDefault() as DataContractAttribute;
name = string.IsNullOrEmpty(attrName.Name) ? asType.Name : attrName.Name;
}
else
{
name = asType.Name;
}
return name;
}
我目前正在使用它从装饰有各种属性的对象中删除元数据。在此示例中,它正在查找DataContractAttribute
然后从 Name 属性中提取值。这工作正常。
但是,有时该对象属于该PropertyInfo
类型。正在发生的事情是Attribute.IsDefined
测试为真,因此进入要抓取的块,但是,它没有投射,所以attrName
出来为空。
我在前一个块之前添加了这个块:
if (obj is PropertyInfo)
{
var asPropInfo = obj as PropertyInfo;
if (Attribute.IsDefined(asPropInfo, typeof(DataMemberAttribute)) || Attribute.IsDefined(asPropInfo, typeof(DataContractAttribute)))
{
var attrName = asPropInfo.GetType().GetCustomAttributes(typeof(Attribute), true).SingleOrDefault();
if (attrName is DataMemberAttribute)
{
var attr = attrName as DataMemberAttribute;
name = string.IsNullOrEmpty(attr.Name) ? asType.Name : attr.Name;
}
else if (attrName is DataContractAttribute)
{
var attr = attrName as DataContractAttribute;
name = string.IsNullOrEmpty(attr.Name) ? asType.Name : attr.Name;
}
}
}
该IsDefined
检查仍在测试中,但仍然无法施放。我通过监视变量查看CustomAttributes
了obj
(当它进入方法时)的属性,它显示了 type 的 1 个属性DataContractAttribute
,但是,当我到达 asPropInfo.GetType() 时,它已更改为Serializable
.
可能是我在这方面已经太久了,我并不清楚,但是有人有什么意见吗?
更新:我能够删除GetType()
并直接调用GetCustomAttributes()
,但是,结果仍然不是我需要的。以下是似乎正在发生的事情:
想象一个 Person 类包含一个 Person 类型的成员,如下所示:
[DataContract(Name = "Employee")]
public class PersonDto{
public string FirstName {get;set;}
public string LastName {get;set;}
[DataMember(Name = "Boss")]
public Person Supervisor {get;set;}
}
在抓取期间发生的事情是Supervisor
作为 PropertyInfo 及其属性传入DataMember
,我的扩展程序正在读取它并返回“Boss”,这完全有道理。但是,在这个阶段我真正需要的是DataContract
属性,原因如下:
当Supervisor
属性被序列化时,它将被序列化为“Boss”,我需要知道这一点,所以我将它保存到 DTO。但是,我还需要知道“老板”是序列化的“类型”,即“员工”。这可能看起来很奇怪,但最终是有道理的,哈哈。我正在使用它来帮助为我们的 API 生成帮助文档。在内部,类类型可能是“PersonDto”,但显示给客户端的类型是“Employee”。因此,在帮助文档方面,开发人员知道有一个“老板”元素,但他们还需要知道它只是“员工”的一个实例(就他们而言),以便他们可以查找该对象的文档。这有意义吗?