为什么C#会允许这样:
public class MyClass
{
static int A=1;
static int B=A+1;
}
Run Code Online (Sandbox Code Playgroud)
但是不允许("字段初始值设定项不能引用非静态字段,方法或属性")这个
public class MyClass
{
int A=1;
int B=A+1;
}
Run Code Online (Sandbox Code Playgroud)
我认为它的 顺序是连续的初始化为它出现这是保证(静态字段),但它也应用在这里你可以看到:
public class MyClass
{
int A=((Func<int>)(delegate(){ Console.WriteLine ("A"); return 1;}))();
int B=((Func<int>)(delegate(){ Console.WriteLine ("B"); return 2;}))();
int C=((Func<int>)(delegate(){ Console.WriteLine ("C"); return 3;}))();
}
void Main()
{
var a = new MyClass();
}
Run Code Online (Sandbox Code Playgroud)
结果:
A
B
C
Run Code Online (Sandbox Code Playgroud)
题
我对它被限制的原因/逻辑更感兴趣.只是为了好奇.
nb没有发现任何重复.
我无法弄清楚为什么它在寻找静态的东西:
public class DatabaseBase
{
private readonly string connectionString;
public DatabaseBase(string connectionString)
{
this.connectionString = connectionString;
}
}
public class MyDB : DatabaseBase
{
readonly string connectionString = ConfigurationManager.AppSettings["MyConnectionString"];
public MyDB() : base(connectionString)
{
}
}
Run Code Online (Sandbox Code Playgroud)
我得到了无法在静态上下文中访问非静态字段'connectionString'.我在基础数据库类中看不到任何静态,为什么?
这是另一个我们做同样事情的例子:
partial class Database : DatabaseBase
{
static string DbConnectionString
{
get
{
if (dbConnectionString == null)
dbConnectionString =
ConfigurationManager.AppSettings["MyConnectionString"];
return dbConnectionString;
}
}
public Database() :base(DbConnectionString)
{
}
Run Code Online (Sandbox Code Playgroud)
好吧,为什么它必须是连接字符串传递的静态字符串?
这个问题是Cristi Diaconescu关于this在C#中访问字段初始化程序的非法性的扩展.
这在C#中是非法的:
class C
{
int i = 5;
double[] dd = new double[i]; //Compiler error: A field initializer cannot reference the non-static field, method, or property.
}
Run Code Online (Sandbox Code Playgroud)
好的,所以合理解释为什么这是非法的,其中包括Eric Lippert:
简而言之,在构造函数体运行之前访问接收器的能力是边缘效益的特征,这使得编写错误程序更容易.因此,C#语言设计者完全禁用它.如果需要使用接收器,则将该逻辑放在构造函数体中.
此外,C#规范非常简单(直到某一点):
实例字段的变量初始值设定项无法引用正在创建的实例.因此,在变量初始化程序中引用它是一个编译时错误,因为变量初始化程序通过简单名称引用任何实例成员是编译时错误.
所以我的问题是:" 通过一个简单的名字 "是什么意思?
是否存在合法的替代机制?我确信规范中几乎每个单词都有一个非常具体的原因,那么通过简单的名称将这个特定代码的非法性限制为引用的原因是什么?
编辑:我没有把我的问题措辞得太好.我不是要求" 简单名称 " 的定义,我问的是将非法性限制在特定情况的原因.如果以任何方式引用任何实例成员始终是非法的,那么为什么要如此狭窄地指定呢?如果不是,那么什么机制合法呢?