我已经阅读了各地const和static readonly各个领域.我们有一些只包含常量值的类.用于我们系统中的各种事物.所以我想知道我的观察结果是否正确:
这些常量值是否应始终static readonly适用于所有公开的内容?并且仅const用于内部/受保护/私有值?
您有什么推荐的吗?我是否可能甚至不使用static readonly字段,而是使用属性?
在以下程序中:
class Main
{
static string staticVariable = "Static Variable";
string instanceVariable = "Instance Variable";
public Main(){}
}
Run Code Online (Sandbox Code Playgroud)
在instanceVariable将存储分配给对象实例的记忆里.staticVariable存储在哪里,是存储在对象实例本身还是其他地方?如果它存储在其他地方,内存位置如何连接?
问题实际上非常简单.以下代码在其下面引发异常:
class Foo
{
public const StringBuilder BarBuilder = new StringBuilder();
public Foo(){
}
}
Run Code Online (Sandbox Code Playgroud)
错误:
Foo.BarBuilder'的类型为'System.Text.StringBuilder'.除string之外的引用类型的const字段只能用null初始化.
MSDN说这是我理解的,从const视角来说它是有道理的:
常量表达式是一个可以在编译时完全计算的表达式.因此,引用类型常量的唯一可能值是string和null引用.
但是,我没有看到我们使用null常数的原因或原因.那么为什么首先可以定义一个引用类型(除了字符串),const如果它只能被设置为null,如果它是一个故意的决定(我相信它是)那么我们在哪里可以使用常量值和空值?
更新:
当我们想到答案时,请让我们的思维方式不同于"我们有这个,所以为什么不......"背景.
为什么可以readonly使用反射修改字段的值而不是a的值const?
class Program
{
static void Main(string[] args)
{
Foobar foobar = new Foobar();
Console.WriteLine(foobar.foo); // Outputs "Hello"
Console.WriteLine(Foobar.bar); // Outputs "Hello"
var field = foobar.GetType().GetField("foo");
field.SetValue(foobar, "World"); // Ok
field = foobar.GetType().GetField("bar");
field.SetValue(foobar, "World"); // Throws FieldAccessException
Console.ReadKey();
}
}
public class Foobar
{
public readonly string foo = "Hello";
public const string bar = "Hello";
}
Run Code Online (Sandbox Code Playgroud)
我已经阅读了这个答案,所以我明白它可以违反规则,readonly但为什么不能const这样呢?我确信这是一个很好的理由,但我无法弄清楚它可能是什么.
- 编辑 -
当我使用ildasm查看上面的代码时,该readonly字段的值在编译时设置.不是在字段本身,const而是在类的构造函数中.所以我不确定为什么可以"覆盖"而不是另一个.
我的意思是,即使const二进制文件中的"硬编码"值是不能修改框架本身的技术限制的原因,因为"它已经设置"或只是一个设计决策.我没有看到任何理由为什么某些地方没有某种"魔法"修改它 …
我在解决方案中有大约3个项目的解决方案.这三个项目共享一些常见的常量,直到现在,我一直在三个项目之间进行复制和粘贴.
我想要做的是创建一个包含这些常量的程序集,并仅引用另一个项目中的程序集.问题是,我想我曾经记得在编译项目时曾经读过的地方,常量值只是从程序集"复制并粘贴"到引用它的程序集中.这意味着如果我想改变其中一个常量的值,我不能只改变一个组件.我必须再次重新编译整个解决方案.
任何人都可以确认这是否属实,如果是,请告诉我这样做的首选和替代方法,以便我可以更改我的程序集中的常量?