gpt4 book ai didi

c# - 带有 GetFields 和 GetProperties 的 DumpObject,例如带有嵌套类

转载 作者:行者123 更新时间:2023-11-30 17:08:58 24 4
gpt4 key购买 nike

这是我在 stackoverflow 中的第一个问题,我是使用反射的初学者。

我想转储对象实例的所有值以供引用(以跟踪测试中使用的值)。我使用的是 Compact Framework 3.5 而不是完整的框架。请记住这一点以提出您的建议。

想象以下类:

public class Camera : IDisposable
{
public Camera.FilenameProperties SnapshotFile;
public double DigitalZoomFactor { get; set; }
public bool DisplayHistogram { get; set; }
public int ImageUpdateInterval { get; set; }
public Camera.ImprintCaptionPosType ImprintCaptionPos { get; set; }
public string ImprintCaptionString { get; set; }
}

“特殊”类型是:

    public class FilenameProperties
{
public string Directory { get; set; }
public string Filename { get; set; }
public Camera.FilenamePaddingType FilenamePadding { get; set; }
public Camera.ImageType ImageFormatType { get; set; }
public Camera.ImageResolutionType ImageResolution { get; set; }
public int JPGQuality { get; set; }

public void Restore();
public void Save();

public enum Fnametype
{
tSnapshot = 0,
tCircularCapture = 1,
}
}
public enum ImprintCaptionPosType
{
Disabled = 0,
LowerRight = 1,
LowerLeft = 2,
LowerCenter = 3,
UpperRight = 4,
UpperLeft = 5,
UpperCenter = 6,
Center = 7,
}

现在,我可以获得相机实例的“基本”名称和属性以及字段名称:

Camera cam = new Camera();
dumpProperties(cam);
...
void dumpProperties(object oClass)
{
System.Diagnostics.Debug.WriteLine(oClass.ToString());

FieldInfo[] _Info = oClass.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
for(int i = 0; i<_Info.Length; i++)
{
System.Diagnostics.Debug.WriteLine(_Info[i].Name + ":'" + _Info[i].GetValue(oClass).ToString()+"'");
}

foreach (PropertyInfo pi in oClass.GetType().GetProperties())
{
System.Diagnostics.Debug.WriteLine(pi.Name + ":'" + pi.GetValue(oClass, null)
+ "' Type=" + pi.PropertyType.ToString());
}
}

然后得到这样的东西:

Intermec.Multimedia.Camera
SnapshotFile:'Intermec.Multimedia.Camera+FilenameProperties'
DigitalZoomFactor:'1' Type=System.Double
DisplayHistogram:'False' Type=System.Boolean
ImageUpdateInterval:'1' Type=System.Int32
ImprintCaptionPos:'Disabled' Type=Intermec.Multimedia.Camera+ImprintCaptionPosType
ImprintCaptionString:'' Type=System.String

现在,对于像 DigitalZoomFactor 和 ImageUpdateInterval 这样的简单属性,我得到了我需要的,但是对于嵌套类(正确的措辞?)我只得到了类型,例如 SnapshotFile。对于嵌套枚举,我得到与“ImprintCaptionPos”一样的值。

如何获取嵌套值的值,例如 SnapshotFile 字段/属性的 FilenameProperties.Filename?

如果我使用 dumpProperties(cam.SnapshotFile),我会得到我正在寻找的输出:

Intermec.Multimedia.Camera+FilenameProperties
Directory:'\Program Files\FrmCamera' Type=System.String
Filename:'myphoto' Type=System.String
ImageFormatType:'JPG' Type=Intermec.Multimedia.Camera+ImageType
FilenamePadding:'None' Type=Intermec.Multimedia.Camera+FilenamePaddingType
ImageResolution:'Medium' Type=Intermec.Multimedia.Camera+ImageResolutionType
JPGQuality:'100' Type=System.Int32

但是我怎样才能使它自动化呢?

我进行了大量搜索和测试编码,但无法找到解决方案。问题似乎是让字段的实例能够遍历它。

我没有 Camera 类的源代码,所以我无法在其中添加或删除代码。

有人能帮忙吗?

我需要得到类似调试器显示的东西: enter image description here

最佳答案

你只需要使用递归,如果你的属性是一个类,就循环回到方法中。下面是我们使用的 XML 序列化例程的示例,它使用反射有效地遍历目标的属性,并从中生成一个 XElement。您的逻辑会有所不同,因为您不打算构建 XML,但您将要做的事情的结构非常相似。

public XElement Serialize(object source, 
string objectName,
bool includeNonPublicProperties)
{
XElement element;
var flags = BindingFlags.Instance | BindingFlags.Public;
if(includeNonPublicProperties)
{
flags |= BindingFlags.NonPublic;
}

var props = source.GetType().GetProperties(flags);

var type = source.GetType();

string nodeName;
if(objectName == null)
{
if (type.IsGenericType)
{
nodeName = type.Name.CropAtLast('`');
}
else
{
nodeName = type.Name;
}
}
else
{
nodeName = objectName;
}

element = new XElement(nodeName);

foreach (var prop in props)
{
string name = prop.Name;
string value = null;
bool valIsElement = false;

if (!prop.CanRead) continue;

if(prop.PropertyType.IsEnum)
{
value = prop.GetValue(source, null).ToString();
}
else
{
string typeName;

if (prop.PropertyType.IsNullable())
{
typeName = prop.PropertyType.GetGenericArguments()[0].Name;
}
else
{
typeName = prop.PropertyType.Name;
}

switch (typeName)
{
case "String":
case "Boolean":
case "Byte":
case "TimeSpan":
case "Single":
case "Double":
case "Int16":
case "UInt16":
case "Int32":
case "UInt32":
case "Int64":
case "UInt64":
value = (prop.GetValue(source, null) ?? string.Empty).ToString();
break;
case "DateTime":
try
{
var tempDT = Convert.ToDateTime(prop.GetValue(source, null));
if (tempDT == DateTime.MinValue) continue;
value = tempDT.ToString("MM/dd/yyyy HH:mm:ss.fffffff");
}
catch(Exception ex)
{
continue;
}
break;
default:
var o = prop.GetValue(source, null);
XElement child;
if (o == null)
{
child = new XElement(prop.Name);
}
else
{
child = Serialize(o, prop.Name, includeNonPublicProperties);
}

element.Add(child);
valIsElement = true;
break;
}
}

if (!valIsElement)
{
element.AddAttribute(name, value);
}
}

return element;
}

关于c# - 带有 GetFields 和 GetProperties 的 DumpObject,例如带有嵌套类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13379431/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com