Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/182.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 仅在创建对象时才能指定的类属性?_C# - Fatal编程技术网

C# 仅在创建对象时才能指定的类属性?

C# 仅在创建对象时才能指定的类属性?,c#,C#,在C语言中,可以这样写: Instrument instr = new Instrument { ClassCode = "Hello", Ticker = "World" }; 但是,要做到这一点,您必须添加set: class Instrument { public string ClassCode { get; set; } public string Ticker { get; set; } } 这意味着以后有人可能会意外更改值: instr.ClassCode.se

在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”。

嗯,有可能:)

将set设为private并创建public构造函数,以便可以传递类代码和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
    }
}

添加构造函数并使其成为返回变量的属性:

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; }
    }
}

假设您只是通过构造函数设置值,那么可以显式地编写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;
        }
      }


}

我将通过使用私有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; }
}

一个标准的解决方案是在构造函数中接受属性的初始值-类似这样:

class Instrument
{
  public string ClassCode {get; private set}
  public Instrument (string classCode)
  {
    this.ClassCode = classCode;
  }
}
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");
Instrument instrument = new Instrument(ClassCode: "classCode", Ticker: "ticker");

那么我相信您希望使用构造函数而不是初始化

如果你的班级是

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; }
      }

然后使用友好类初始化值(根据原始代码)并使用公共属性读取值。

发生这种情况的原因是您使用的代码:

Instrument instr = new Instrument { ClassCode = "Hello", Ticker = "World" };
这只是语法上的糖分:

Instrument instr = new Instrument();
instr.ClassCode = "Hello";
instr.Ticker = "World";
上面的两个样本完全相同,前者只是后者的简写

要实现此功能,您需要将这些值设置为私有。大概是这样的:

class Instrument
{
  public string ClassCode {get; private set}
  public Instrument (string classCode)
  {
    this.ClassCode = classCode;
  }
}
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");
Instrument instrument = new Instrument(ClassCode: "classCode", Ticker: "ticker");
这里有:

  • 只能从类内部设置的私有值,因此以后不能被其他人重写
  • 用于读取这些值的公共只读属性
  • 一个私有的默认构造函数,因此没有人可以在不提供必要值的情况下实例化此对象
  • 需要必要值的公共构造函数
您可以这样实例化它:

class Instrument
{
  public string ClassCode {get; private set}
  public Instrument (string classCode)
  {
    this.ClassCode = classCode;
  }
}
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");
Instrument instrument = new Instrument(ClassCode: "classCode", Ticker: "ticker");

这意味着您将无法再使用语法糖(我认为它被称为对象初始值设定项)来实例化类,您必须使用构造函数。因此,对于当前的实现来说,这是一个突破性的改变,但是这是一种生成所需功能的简单方法。

如果您想要有好的语法,那么您可以使用构造函数的默认值

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; } 
}
然后,您可以在代码中创建如下对象:

class Instrument
{
  public string ClassCode {get; private set}
  public Instrument (string classCode)
  {
    this.ClassCode = classCode;
  }
}
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");
Instrument instrument = new Instrument(ClassCode: "classCode", Ticker: "ticker");

如果您热衷于初始值设定项语法,一种典型的方法是创建“冰棒”对象,这些对象一开始可能是流动的,但随后您将其冻结并锁定更改

基本上,我会创建这样的类(用以下方法测试):

void Main()
{
仪器仪表1=新仪器
{
ClassCode=“你好”,
Ticker=“世界”
};
instr1.ClassCode=“123”//是允许的
仪器仪表2=新仪器
{
ClassCode=“你好”,
Ticker=“世界”

}.Freeze();//为什么不使用构造函数呢?老实说,语法并没有什么不同,除非你对那些花括号很着迷。我不使用构造函数,因为我已经有很多代码使用了
新工具{ClassCode=“Hello”,Ticker=“World”}
。我只想现在将
仪器设置为只读,因为它实际上是只读的…如果有人写的话,可能会导致奇怪的问题。set(…)他希望设置新的值…谢谢,这很有趣。但是错误将在运行时报告,而不是在设计时报告。我认为最好还是使用构造函数。