4

我是 C# 新手,如果我的一些概念有偏差,请原谅我。我正在使用佳能 EDSDK,为了让生活更轻松,我希望能够将错误消息视为文本而不是十六进制值。EDSDK.cs 文件包含一长串错误,例如:

public const uint EDS_ERR_TAKE_PICTURE_CARD_NG = 0x00008D07;
public const uint EDS_ERR_TAKE_PICTURE_CARD_PROTECT_NG = 0x00008D08;

理想情况下,我想将所有这些都放入某种查找表中,这样我就可以输入 HEX 错误代码并将实际消息作为字符串返回。例如

Hashtable EDSDKErrorCodes = new Hashtable();

EDSDKErrorCodes.Add("0x00008D01", "EDS_ERR_TAKE_PICTURE_AF_NG");
EDSDKErrorCodes.Add("0x00008D08", "EDS_ERR_TAKE_PICTURE_CARD_PROTECT_NG");
etc etc...

稍后在我的代码中,我可以获取从 EDSDK 方法之一返回的错误消息,并以人类可读的形式显示它:

errorcode= EDSDK.EdsInitializeSDK();

MessageBox.Show(Convert.ToString(EDSDKErrorCodes[errorcode]));

我的问题是..这是处理所有这些错误代码的好方法,还是人们会推荐一种更好、更有效的方法?如果是这样,我如何将我的哈希表填充为一系列常量,而不必使用 Add 方法?

4

6 回答 6

16

另一种方法是创建一个带有描述属性的枚举。有关完整的详细信息,请参见此处。这是总结它的外观:

public enum ErrorCodes : uint
{
    [Description("Description for EDS_ERR_TAKE_PICTURE_CARD_NG")]
    EDS_ERR_TAKE_PICTURE_CARD_NG = 0x00008D07,
    [Description("Description for EDS_ERR_TAKE_PICTURE_CARD_PROTECT_NG")]
    EDS_ERR_TAKE_PICTURE_CARD_PROTECT_NG = 0x00008D08
}

在最简单的情况下,如果您不关心描述,您可以使用Enum.GetName将枚举名称转换为字符串

于 2011-05-17T17:05:12.153 回答
6

您可以为此使用枚举。

public enum ErrorCodes : uint
{
    EDS_ERR_TAKE_PICTURE_CARD_NG = 0x00008D07,
    EDS_ERR_TAKE_PICTURE_CARD_PROTECT_NG = 0x00008D08
}

那么您的用法可能如下所示:

ErrorCodes error = (ErrorCodes)EDSDK.EdsInitializeSDK();
MessageBox.Show(Enum.GetName(typeof(ErrorCodes), error));
于 2011-05-17T17:02:54.540 回答
3

我认为制作枚举会更好:

public enum CanonErrorCode
{
    SomeErrorDescription = 14,
    SomeOtherErrorDescription = 15
    // .. etc
}

您只需将十六进制转换为整数。然后你可以简单地这样称呼它:

// Samples
var myErrorCode = (CanonErrorCode)someIntegerValue;
var myErrorCode = CanonErrorCode.SomeOtherErrorDescription;

如果您想要人工格式化的错误描述,那么我建议您使用某种映射,例如:

static Dictionary<int, string> errorlookups = new Dictionary<int, string>();

errorLookups.Add(10, "This is the human readable error message.");
errorLookups.Add(17, "Create this guy once in a static constructor.");
于 2011-05-17T17:01:33.547 回答
3

您可以使用通用字典而不是哈希表

Dictionary<uint, String> myDict = new Dictionary<uint, String>();

然后,您可以通过执行检索您想要的值

MessageBox.Show(myDict[errorCode]);

对于添加,我认为您可以通过反射来做一些事情来反映 EDSDK 类并找到所有常量 uint 成员。然后遍历该列表,添加值和常量名称。

于 2011-05-17T17:04:06.413 回答
2

好的,因为我们正在滚动 :-)
如果当前错误代码未定义,此解决方案还会生成人类可读的错误字符串。

创建一个Enum这样的:

public enum ErrorCode : uint
{
    EDS_ERR_TAKE_PICTURE_CARD_NG = 0x00008D07,
    EDS_ERR_TAKE_PICTURE_CARD_PROTECT_NG = 0x00008D08
}

然后,为枚举类型创建一个扩展方法,如下所示:

public static class ErrorHandler
{
    public static string ToErrorString(this ErrorCode errorCode)
    {
        return Enum.IsDefined(typeof(ErrorCode), errorCode) ? 
            errorCode.ToString() : "Undefined error code";
    }
}

最后,像这样使用它:

var errorCode = (ErrorCode)EDSDK.EdsInitializeSDK();
MessageBox.Show(errorCode.ToErrorString());
于 2011-05-17T18:15:12.227 回答
0

首先,您应该使用通用字典而不是哈希表。其次,我对佳能 EDSDK 一无所知,但它以十六进制字符串的形式返回错误代码而不是定义常量时的简单 uint 似乎很奇怪。他们真的是这样被退回的吗?如果是这样,那很奇怪,但是您应该能够将它们转换为整数,否则,您可以跳过该步骤。

如果要使用反射创建数组,可以执行以下操作:

Dictionary<int,String> EDSDKErrorCodes = new Dictionary<int,String>;
System.Reflection.FieldInfo[] fields = typeof(EDSDK).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
foreach (System.Reflection.FieldInfo field in fields) {
  EDSDKErrorCodes[(uint)field.GetValue(null)] = field.Name;
}

然后您可以使用以下方式访问它:

MessageBox.Show(EDSDKErrorCodes[errorCode]);

如果 errorCode 是一个字符串,请先使用以下方法对其进行转换:

uint errorNumber = uint.Parse(errorCode.Substring(2), System.Globalization.NumberStyle.HexNumber);
于 2011-05-17T17:07:49.617 回答