在 C# 中,如何动态获取静态类的成员

本文关键字:动态 获取 静态类 成员 何动态 | 更新日期: 2023-09-27 18:35:48

我目前正在尝试使用ZXing库在Windows Phone 7.5中开发移动条形码阅读器。看到我在这里发帖,您可能已经猜到我正面临某种我不知道任何解决方案的问题。

问题如下:ZXing库允许多种条形码格式 - 但是,我想包含一个设置菜单,供用户专注于一个条形码。

BarcodeFormat对象是静态的,包含我要分配的只读成员(BarcodeFormat类型)。

看到和听到反射是这种动态行为的有力武器,我想我会试一试。

到目前为止,我有代码可以使用 ZXing 获取所有可能的格式

MemberInfo[] plist = typeof(BarcodeFormat).GetMembers();

这适用于获取格式的名称,这意味着我可以在列表中成功显示名称。但是在尝试将这些格式分配给实际阅读器时,我遇到了问题,因为我只有会员信息,而不再是条形码格式。

到目前为止,我只找到了用户想要动态访问(设置/获取)变量的示例。然而,提出的解决方案似乎不适合我的问题——至少我没有找到任何以这些方式分配格式的方法。

任何帮助都会很棒:)谢谢。

编辑:条形码格式是这样用的:

WP7BarcodeManager.ScanMode = BarcodeFormat.ITF;

在此示例中,仅接受 ITF(交错 2/5)格式的条形码。

到目前为止,我已经尝试了以下方法。

只需分配 MemberInfo 对象,而不是原始的 BarcodeFormat 对象。

将 MemberInfo 对象强制转换为 BarcodeFormat。

我尝试使用 FieldInfo 和 getValue,但是似乎我必须创建一个示例对象并为所需的字段分配一个值才能获得值。这不能在这里完成,因为对象是静态的,字段是只读的。

整个ZXing库被编译为一个DLL,我将我的项目链接到该DLL。(它似乎链接正确,因为其他一切都有效)。条形码格式的示例声明如下所示

public static readonly BarcodeFormat ITF

在 C# 中,如何动态获取静态类的成员

动态获取ITF:

var formatName = "ITF";
var format = typeof(BarcodeFormat)
   .GetProperty(formatName, BindingFlags.Static | BindingFlags.Public)
   .GetValue(null, null);

设置 WP7BarcodeManager.ScanMode:

WP7BarcodeManager.ScanMode = (BarcodeFormat)format;

附言

条形码格式的成员:

var _format = member is PropertyInfo 
  ? ((PropertyInfo)member).GetValue(null, null)
  : ((FieldInfo)member).GetValue(null);
var format = (BarcodeFormat)_format;

"由于静态属性属于类型,而不是单个对象,因此通过将 null 作为对象参数传递来获取静态属性"

例如:

PropertyInfo CurCultProp = (typeof(CultureInfo)).GetProperty("CurrentCulture"); 
Console.WriteLine("CurrCult: " + CurCultProp.GetValue(null,null));

因此,您需要做的就是调用GetProperties()而不是GetMembers()并调用GetValue(null, null)以获取值。

我不完全明白你为什么要经历反思的麻烦。

您可以像这样枚举条形码类型(好的虚拟代码,您可能应该绑定到列表框/选择器,但是.. ):

var mgr = new BarcodeTypeManager();
foreach (var barCode in mgr.BarcodeTypes)
{  
  WP7BarcodeManager.ScanMode = barCode.BarcodeType;
}

(事实上,您还可以使用BarcodePhotoChooser选取器。

如果用户可以保存首选类型,则可以轻松地再次查找它:

var typeToUse = mgr.BarcodeTypes.Where(b => b.Name == "what user selected").FirstOrDefault();
WP7BarcodeManager.ScanMode = typeToUse.BarcodeType;