在C#中可以这样写:
Instrument instr = new Instrument { ClassCode = "Hello", Ticker = "World" };
但要这样做,您必须在相应的类中添加set;
:
class Instrument
{
public string ClassCode { get; set; }
public string Ticker { get; set; }
}
这意味着以后某人可能会意外更改值:
instr.ClassCode.set = "Destroy"
而且我不想允许这样做。即,一方面我想要一个只读属性,另一方面我想创建这样的对象:
Instrument instr = new Instrument { ClassCode = "Hello", Ticker = "World" };
我不确定这是否可行。可能我应该使用字段或其他东西而不是属性。我只想拥有最后一句话的语法,但同时保持只读。
upd:简而言之,不允许以任何方式使用只读属性。在这种情况下,应使用常规构造函数和“get”。
答案 0 :(得分:7)
我将通过使用私有setter并从构造函数中调用它来实现此目的。通过这种方式,您可以控制何时调用setter。
Instrument instr = new Instrument("Hello", "World");
class Instrument
{
public Instrument(string ClassCode, string Ticker)
{
this.ClassCode = ClassCode;
this.Ticker = Ticker;
}
public string ClassCode { get; private set; }
public string Ticker { get; private set; }
}
答案 1 :(得分:3)
这是因为你正在使用的代码:
Instrument instr = new Instrument { ClassCode = "Hello", Ticker = "World" };
只是语法糖:
Instrument instr = new Instrument();
instr.ClassCode = "Hello";
instr.Ticker = "World";
上面的两个样本完全相同,前者只是后者的简写。
您希望实现此功能的目的是将这些值设为私有。像这样:
class Instrument
{
private string _classCode;
private string _ticker;
public string ClassCode{ get { return _classCode; } }
public string Ticker{ get { return _ticker; } }
private ClassCode() {}
public ClassCode(string classCode, string ticker)
{
_classCode = classCode;
_ticker = ticker;
}
}
你在这里有:
你可以像这样实例化它:
Instrument instr = new Instrument("Hello", "World");
这意味着您将无法再使用语法糖(对象初始值设定项,我认为它被调用)来实例化该类,您必须使用构造函数。因此,这将是当前实现的一个重大变化,但却是产生所需功能的简单方法。
答案 2 :(得分:2)
如果您倾向于使用初始化程序语法,那么执行此操作的典型方法是创建“popsicle”对象,可以开始流畅的对象,但随后冻结它们并锁定更改。
基本上,我会创建这样的类(使用LINQPad测试):
void Main()
{
Instrument instr1 = new Instrument
{
ClassCode = "Hello",
Ticker = "World"
};
instr1.ClassCode = "123"; // is allowed
Instrument instr2 = new Instrument
{
ClassCode = "Hello",
Ticker = "World"
}.Freeze(); // <-- notice Freeze here
instr2.ClassCode = "123"; // throws InvalidOperationException
}
public class Instrument
{
private string _ClassCode;
private string _Ticker;
private bool _IsFrozen;
public string ClassCode
{
get { return _ClassCode; }
set
{
ThrowIfFrozen();
_ClassCode = value;
}
}
public string Ticker
{
get { return _Ticker; }
set
{
ThrowIfFrozen();
_Ticker = value;
}
}
private void ThrowIfFrozen()
{
if (_IsFrozen)
throw new InvalidOperationException(
"Instrument object has been frozen");
}
public Instrument Freeze()
{
_IsFrozen = true;
return this;
}
public bool IsFrozen
{
get
{
return _IsFrozen;
}
}
}
答案 3 :(得分:1)
嗯,有点可能:)
make set private并创建公共构造函数,以便您可以传递ClassCode和Ticker,即:
class Instrument
{
public string ClassCode { get; private set; }
public string Ticker { get; private set; }
public Instrument(ClassCode classCode, Ticker ticker)
{
ClassCode = classCode;
Ticker = ticker
}
}
答案 4 :(得分:1)
假设您只是通过构造函数设置值,您可以显式编写set方法以检查它分配的字段是否为未分配(null或其他),如果未分配,则仅写入集合中的值。这样你的设置就可以有效地写入一次。它会在那里大部分时间。
class Instrument
{
private string _classCode;
private string _ticker;
public string ClassCode
{
get
{
return _classCode;
}
set
{
if (_classCode == null)
_classCode = value;
}
}
public string Ticker {
get
{
return _ticker;
}
set
{
if (_ticker == null)
_ticker = value;
}
}
}
答案 5 :(得分:1)
一个标准解决方案是在构造函数中接受属性的初始值 - 如下所示:
class Instrument
{
public string ClassCode {get; private set}
public Instrument (string classCode)
{
this.ClassCode = classCode;
}
}
答案 6 :(得分:0)
添加构造函数并使它们成为返回变量的属性:
class Instrument
{
private string classCode;
private string ticker;
Instrument(string classCode, string ticker)
{
this.classCode = classCode;
this.ticker = ticker;
}
public string ClassCode
{
get { return classCode; }
}
public string Ticker
{
get { return ticker; }
}
}
答案 7 :(得分:0)
然后我相信你想使用构造函数而不是初始化。
如果你的班级是
class Instrument
{
private string _ClassCode;
private string _Ticker;
public Instrument(string ClassCode, string Ticker)
{
_ClassCode = ClassCode;
_Ticker = Ticker;
}
public string ClassCode { get {return _ClassCode;}}
public string Ticker { get {return _Ticker;} }
}
你会得到预期的效果。
或强>
您可以使用不同的访问级别创建单独的属性,例如:
private string _ClassCode;
internal string ClassCodeSet
{
set { _ClassCode = value; }
}
public string ClassCode
{
get { return _ClassCode; }
}
然后使用友好类初始化值(根据您的原始代码)和公共属性来读取值。
答案 8 :(得分:0)
如果你想拥有漂亮的语法,那么你可以使用你的constuctor的默认值
class Instrument {
public Instrument(string ClassCode = null, string Ticker = null)
{
this.ClassCode = ClassCode;
this.Ticker = Ticker;
}
public string ClassCode { get; private set; }
public string Ticker { get; private set; }
}
然后您可以在代码中创建对象:
Instrument instrument = new Instrument(ClassCode: "classCode", Ticker: "ticker");