pre-defined constants for non-trivial data types
我的目标:为既有ID又有消息的预定义错误创建一个C类。以下是我的尝试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
这本书汇编得很好,我相信它在实践中会很好地发挥作用。但我总是喜欢遵循代码分析准则。在上述情况下,违反了CA2104"不要声明只读可变引用类型"
我尝试了很多其他方法,包括尝试const而不是readonly(甚至不编译)、get;private set;用于成员访问、struct而不是类等。
哪个是可变类型?身份证还是留言?
我愿意接受任何实现我想要的功能的建议:为非琐碎的数据类型预先定义常量。
当然,我可以忽略这个警告,但我发现这通常是有原因的。
*澄清*我的问题实际上不是关于这个特定的myError类,而是关于为基本数据类型以外的东西定义常量的更基本的问题。
假设我要定义三个双精度常量。让我这样做:
1 2 3 | public const double HighValue = 11.0; public const double LowValue = 0.1; public const double MidValue = 5.5; |
C为我们预先定义的双重常量创建少量有用的常量:NaN、MinValue、MaxValue、NegativeInfinity、PositiveInfinity。
那么现在,如果我想为空间中的三维向量(x,y,z)预先定义一些有趣的常数呢?我可以为双精度数、整数、字符串等定义常量,但是如何为一些不那么简单的东西定义常量呢?原点是一个有趣的常量,我想给它起个名字:
1 2 3 4 5 6 7 8 9 | public class Vector3D { /// The problem is that this does not work public const Vector3D Origin = { 0.0, 0.0, 0.0 }; public double X; public double Y; public double Z; } |
我不需要上千个常量。只有一些像我们的朋友Double和Nan等。班级也不需要特别保护或密封。任何人都可以自由地创建vector3d对象并以任何方式从中派生。我只想有一个特殊的常量名为origin,它有值(0.0,0.0,0.0)
类型不可变。代码分析会被公共只读字段混淆。
您可以通过使公共字段成为公共属性来解决代码分析问题:
1 2 3 4 5 6 7 8 9 | public MyError(int id, string message) { this.id = id; this.message = message; } private readonly int id; private readonly string message; public int Id { get { return id; } } public string Message { get { return message; } } |
您的类型不是可变的,但代码分析不知道这一点。这个警告是一个误报;您应该抑制它。
要回答您编辑的问题:
只要类型是正确不变的,它就可以完美地工作。
您的属性不应该是静态的,因为此类的每个实例都有自己的ID和消息,您同意吗?
我会创建一个类
- 是密封的,以防止它被继承
- 有一个私有构造函数,以防止从类外部实例化它
- 为属性提供私有setter,因此不能从外部设置它们。
这将为您提供以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public sealed class MyError { public static readonly MyError OK = new MyError(0,"OK"); public static readonly MyError Bad = new MyError(1,"Bad Stuff"); private MyError(int id, string message) { this.ID = id; this.Message = message; } public int ID { get; private set; } public string Message { get; private set; } } |