2011-05-17 72 views
3

我是C#的新手,因此如果我的某些概念出现偏差,请原谅我。我正在使用Canon EDSDK,为了让生活更轻松,我希望能够将错误消息看作文本而不是十六进制值。该EDSDK.cs文件包含错误,如一个长长的清单:关于在C中构建错误代码查找的建议#

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

理想情况下,我想将所有的这些成某种查找表,所以我可以输入一个十六进制错误代码,并返回实际消息一个字符串。例如

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方法?

回答

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)); 
+0

这似乎对我来说是完美的,因为一切都在一个列表中,无需交叉引用它对字典。非常感谢您的快速帮助。 – mrbencowell 2011-05-17 17:11:24

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."); 
+0

你打败了我:-)可以添加,你可以创建一个小的静态错误查找包装类'字符串ToErrorString(uint errorCode)'方法,执行查找字典。 – 2011-05-17 17:04:47

+0

我刚刚发布几乎相同的解决方案,但你得到了领导:) – Maverik 2011-05-17 17:05:07

2

你可以使用一个通用字典,而不是一个哈希表

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

然后你可以检索你想要的值做

MessageBox.Show(myDict[errorCode]); 

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

12

另一种可以做到这一点的方法是创建一个带有描述属性的Enum。详情请参阅here。这是总结它会怎样看:

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 
} 

在非常简单的,如果你一个说明didnt照顾,你可以在枚举名称转换为使用Enum.GetName

+1

酷..我刚刚从这里了解到Description属性!谢谢:) – Maverik 2011-05-17 17:06:12

+0

我也是..这真是太棒了..谢谢你! – mrbencowell 2011-05-17 17:18:48

0

首先的字符串,你应该使用通用字典而不是散列表。其次,我对Canon EDSDK一无所知,但它似乎很奇怪,它将一个错误代码作为一个十六进制字符串返回,而不是仅仅定义一个常量。这真的是他们如何被退回?如果是这样,那很奇怪,但你应该能够将它们转换为整数,否则,你可以跳过这一步。

如果你想创建一个使用反射阵列,你可以做这样的事情:

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]); 

如果错误码为一个字符串,转换它首先使用:

uint errorNumber = uint.Parse(errorCode.Substring(2), System.Globalization.NumberStyle.HexNumber); 
1

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

创建Enum像这样:

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

然后,对于枚举类型这样创建Extension Method

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());