我想从设置中设置一个const字符串。
如果我想在将来改变程序语言,这很容易; 只需要修改相应的设置!
尝试时:
private const string constString =
"-&" + Properties.Settings.Default.constStringText;
我收到此错误:
The property or indexer 'Properties.Settings.Default'
cannot be used in this context because it lacks the get accessor.
有什么想法吗?
答案 0 :(得分:2)
由于您打算将此作为可选方法参数的默认值,即:
public void Foo(string something = constString)
{
//do something
}
此constString
必须是编译时常量。来自the MSDN page for "Named and Optional Arguments":
默认值必须是以下类型的表达式之一:
一个常量表达式;
新形式ValType()的表达式,其中ValType是值类型,例如枚举或结构;
表单default(ValType),其中ValType是值类型。
因此,实际上无法在运行时从配置文件中读取值,然后将其用于可选参数。
一种解决方法是将constString
声明为readonly
字段:
private readonly string constString =
"-&" + Properties.Settings.Default.constStringText;
然后创建所需的可选参数,并为不使用该参数的方法创建包装重载。该重载依次调用旧方法,并在运行时解析默认值:
public void Foo(string something) //no longer optional
{
//do something
}
public void Foo()
{
Foo(constString); //calls the other overload with the default value
}
答案 1 :(得分:1)
99%的与错误命名空间相关的案例存在此错误。
您可能已经生成了一些使用Properties.Settings.Default
解决方案:检查该类文件中的命名空间。它必须与存储该特定设置的App.config(Web.config)中的标记名称相同。
答案 2 :(得分:1)
虽然Chris Sinclair’s answer(一个const
成员必须具有值类型并且在编译时可以评估,所以使用readonly
)是正确的,我想解释这些限制并回答隐含的问题编译器消息意味着什么,虽然令人失望的评论似乎只是编译器中的错误。
属性或索引器'Properties.Settings.Default'不能在此上下文中使用,因为它缺少get访问器。
此消息表明,通过添加getter(以及其他可能的东西)可以使表达式Properties.Settings.Default
可接受 - 据我所知,这完全是错误的。毕竟,一方面,当提问者向我们保证 1 时,有一个吸气剂,而另一方面,正如克里斯所解释的那样,表达式无效的原因是在编译时无法评估 - 时间,永远不可能,因为它取决于运行时配置。
据推测,此消息适用于其他情况,并且此处已被误用。
1 我在MSVS 2013中也看到了这一点,当默认参数值引用具有getter的属性时 - 但至少它也报告了“默认参数值for '<parname>
'必须是编译时常量“。
const
成员和默认参数值对值类型的限制(如C#5.0语言规范,2012)似乎不完全不可避免 ,但是其他语言设计决策的可理解后果。
static
方法的委托值也可以在编译时被认为是完全确定的,绑定到不可变对象的那些值也支持这个概念。static
) readonly constString
代替const constString
,以明确虽然价值不会改变,直到运行时,在课堂或对象初始化时才确定(如Chris的回答)。如果要将表达式用作可选参数的默认值,必须才能成为真正的编译时常量,为您提供两种可能:
宣布过载,如Chris的回答,例如:
Foo() { Foo(Default); } Foo(string s) { Bar(s); }
。
使用null
作为默认约定,并在您的方法中解释:
Foo(string s = null) { Bar(s != null ? s : Default); }
。
null
不是Foo(string)
支持的参数时才有效,并且在文档注释中一定要明确。 或许:应用Optional
属性,如以下问题:behaviour of Optional attribute:
Foo([Optional] string s) { Bar(etc.?); }
。
= null
,除非null
可能是Foo(string)
支持的参数{1}}。 ¹语言规范5.0§10.5.2.210.5.2.2 常量和static readonly
字段的版本控制
²我记得读过这篇文章,但没有在语言规范中找到它。
答案 3 :(得分:0)
我最近遇到过这种情况,在搜索解决方案时,我偶然发现了这个页面。基于上面的例子,我能够像这样解决我的问题:
private static readonly String ConStr
= string.Format("Data Source={0};Initial Catalog={1}; User ID={2}; Password={3};",
Properties.Settings.Default.DataSource,
Properties.Settings.Default.Catalog,
Properties.Settings.Default.UserID,
Properties.Settings.Default.Password);
只是想分享。