我的目标:为具有ID和消息的预定义错误创建C#类。 这是我试过的:
public class MyError
{
public static readonly MyError OK = new MyError(0, "OK");
public static readonly MyError Bad = new MyError(1, "Bad Stuff");
public MyError(int id, string message)
{
this.Id = id;
this.Message = message;
}
public readonly int Id;
public readonly string Message;
}
这个编译得很好,我相信它在实践中会很好用。但我总是喜欢遵守代码分析指南。在上述情况下,违反了CA2104“不要声明只读可变引用类型”
我尝试了除上述之外的一些事情,包括尝试const而不是readonly(甚至不会编译),{get;私人集;用于成员访问,struct而不是类等。
哪种类型可变?我还是留言?
我愿意接受任何能够实现我想要的建议:非平凡数据类型的预定义常量。
当然,我总是可以忽略警告,但我发现通常有这样的理由。
*澄清* 我的问题实际上不是关于这个特定的MyError类,而是更多关于为基本数据类型之外的东西定义常量的更基本的问题。
假设我想定义三个双精度常量。 C#让我这样做:
public const double HighValue = 11.0;
public const double LowValue = 0.1;
public const double MidValue = 5.5;
C#为我们预先定义的 double 创建了少量有用的常量: NaN , MinValue , MaxValue , NegativeInfinity , PositiveInfinity 。
现在,如果 I 想要在空间中为三维向量(X,Y,Z)预先定义一些有趣的常量,该怎么办?我可以为双精度,整数,字符串等定义常量,但是如何为不那么微不足道的东西定义常量呢? Origin是一个有趣的常数,我想给它起一个名字:
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)
答案 0 :(得分:2)
您的类型不可变,但代码分析不知道。
这个警告是误报;你应该压制它。
回答您编辑过的问题:
const
只能应用于基元
对于自定义类型,static readonly
是唯一选项。
只要类型是正确不可变的,它就能完美地运行。
答案 1 :(得分:2)
类型不可变。公共只读字段使代码分析变得混乱。
您可以通过将公共字段设为公共属性来修复代码分析问题:
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; } }
答案 2 :(得分:1)
您的属性不应该是静态的,因为此类的每个实例都有自己的ID和消息,您同意吗?
答案 3 :(得分:0)
我会创建一个
的类这会给你以下代码:
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; }
}