通常,LINQPad中的.Dump()
扩展方法将XNode
及其派生类实例显示为呈现的XML片段。有时,在开发代码时,我希望以转储其他类型的表形式查看对象的实际属性,例如显示节点及其{{1的Name,Value,FirstAttribute和whatsnot属性的表}}值,或子对象的交互式可扩展集合。简而言之,好像根本没有对XNode进行特殊处理。
我正在通过转储单个属性来解决此问题,但这很繁琐。
This answer建议编写一个自定义扩展代码,以实现另一种类型(即IEnumerable)的类似效果,但这种情况似乎比我正在处理的情况更狭窄,更罕见。
是否有一种开箱即用的方式来做我想做的事?
答案 0 :(得分:0)
LINQPad支持为类型自定义Dump
。使用某些扩展方法,您可以将类型转换为ExpandoObject
,然后将它们与属性一起输出。
在“我的扩展”中,在MyExtensions
类之后,添加一个顶级方法:
static object ToDump(object obj) {
if (obj is XObject x)
return x.ToExpando();
else
return obj;
}
在MyExtensions
类中,添加以下扩展方法。我已经有了object
-> Dictionary
方法来转换为匿名对象,所以我使用了这些方法,但是您可以将它们结合起来在ToExpando
上创建单个object
:< / p>
public static ExpandoObject ToExpando(this object obj) => obj.ToDictionary().ToExpando();
public static IDictionary<string, object> ToDictionary(this object obj) {
if (obj is IDictionary<string, object> id)
return id;
else {
var dictAnsObj = new Dictionary<string, object>();
foreach (var prop in obj.GetType().GetPropertiesOrFields()) {
try {
dictAnsObj.Add(prop.Name, prop.GetValue(obj));
}
catch (Exception ex) {
dictAnsObj.Add(prop.Name, ex);
}
}
return dictAnsObj;
}
}
public static ExpandoObject ToExpando(this IDictionary<string, object> objDict) {
var e = new ExpandoObject();
var di = (IDictionary<string, object>)e;
foreach (var kvp in objDict)
di.Add(kvp);
return e;
}
您还将需要此Type
扩展名:
// ***
// *** Type Extensions
// ***
public static List<MemberInfo> GetPropertiesOrFields(this Type t, BindingFlags bf = BindingFlags.Public | BindingFlags.Instance) =>
t.GetMembers(bf).Where(mi => mi.MemberType == MemberTypes.Field | mi.MemberType == MemberTypes.Property).ToList();
如果可以只以类格式显示顶级对象,则可以在需要时使用此扩展方法:
public static T DumpAs<T, NewT>(this T obj, Func<T, NewT> castFn, string description = null) {
if (description != null)
castFn(obj).Dump(description);
else
castFn(obj).Dump();
return obj;
}
例如,
XElement xn;
xn.DumpAs(x => x.ToExpando());
否则,您将必须注释掉ToDump
方法或使用流利的方法进行一些棘手的操作才能将其打开和关闭。
答案 1 :(得分:0)
此答案取决于先前的答案,但需要时,可以使用其他扩展方法和XObject
方法将其扩展为将转储ToDump
作为类处理。否则,它使用与我以前的答案相同的扩展名。
在MyExtensions
类中,添加新的转储类型和bool
来跟踪状态:
public static bool bDumpAsClass = false;
public static object DumpAsClass(this object input, string descr = null) {
bDumpAsClass = true;
if (descr != null)
input.Dump(descr);
else
input.Dump();
bDumpAsClass = false;
return input;
}
在MyExtensions
类之外,添加使用ToDump
的{{1}}方法:
bool
然后,当您要将static object ToDump(object obj) {
if (MyExtensions.bDumpAsClass) {
if (obj is XObject x)
return x.ToExpando();
}
return obj;
}
或后代作为类转储时,只要扩展任何成员,就可以只使用DumpAsClass
而不是Dump
。
很明显,您可以扩展XObject
为true时处理的类型。