繁体   English   中英

有没有办法在不使用构造函数的情况下初始化结构的成员?

[英]Is there a way to initialize members of a struct without using a constructor?

我有一个包含两个列表的struct

struct MonthData
{
   public List<DataRow> Frontline;
   public List<DataRow> Leadership;
}

但是,我想在创建结构时初始化它们。 如果我尝试:

struct MonthData
{
   public List<DataRow> Frontline = new List<DataRow>();
   public List<DataRow> Leadership = new List<DataRow>();
}

然后我得到:

Error   23  'MonthData.Frontline': cannot have instance field initializers in structs
...

由于结构不能有无参数构造函数,我不能只在构造函数中设置它。 到目前为止,我只能看到以下选项:

  1. 在创建MonthData实例时初始化这两个属性
  2. 使用类而不是结构
  3. 使用参数创建构造函数并使用它
  4. 为懒惰初始化它们的属性创建getter和setter。

推荐的方法是什么? 现在,我在想这个课程是最好的主意。

你应该使用一个班级。 来自MSDN

通常,类用于建模更复杂的行为,或者在创建类对象后要修改的数据。 结构最适合于主要包含在创建结构后不打算修改的数据的小型数据结构。

如果您只是询问语法...尝试构建和使用静态工厂...通常,结构应该用于不可变的东西,而工厂(调用私有构造函数)是一种更好的方法对于不可变类型而不是使用公共构造函数。

  struct MonthData 
  {    
      public List<DataRow> Frontline;
      public List<DataRow> Leadership; 
      private MonthData(List<DataRow> frontLine = null, 
                        List<DataRow> leadership = null)
      { 
         Frontline = frontLine?? new List<DataRow>();
         Leadership = leadership?? new List<DataRow>();  
      }
      public static MonthData Factory(
          List<DataRow> frontLine= null, 
          List<DataRow> leadership= null)
      { return new MonthData(frontLine, leadership); }
  } 

你无论如何都在你的struct中使用引用类型( List<T> ),因此使用struct作为值类型对我没有任何意义。 我只是去上课。

使用构造函数无法做到这一点。 CLR可以并且将创建结构的实例,只需将零初始化内存并避免任何ctor开销。 但是,您可以利用此知识并创建具有相同可观察效果的延迟初始化属性。

例如:

struct MonthData {  
  private bool m_initialized;
  private List<DataRow> m_frontLine;
  private List<DataRow> m_leaderShip;

  public List<DataRow> FrontLine {
    get {
      EnsureInitialized(); 
      return m_frontLine;
    }
  }

  public List<DataRow> LeaderShip {
    get {
      EnsureInitialized(); 
      return m_leaderShip;
    }
  }

  void EnsureInitialized() {
    if (!m_initialized) {
      m_initialized = true;
      m_frontLine = new List<DataRow>();
      m_leaderShip = new List<DataRow>();
    }
  }
}

如果CLR允许一种保证结构类型的东西可以在它们对这些代码之外的任何东西可见之前运行一些初始化代码的方法,那将是很好的。 即使在创建结构类型的数组时,也可以这样做,方法是在对数组本身的引用暴露在任何地方之前让CLR通过引用传递数组的所有单个元素。 不幸的是,如果在创建数组期间抛出异常,它将导致一种尴尬的情况。 如果构造函数没有任何副作用,那就没有问题 - 只需丢弃数组并假装即使成功创建的对象也不存在。 然而,具有副作用的构造者可能会造成一些困难。

但是,实际上,没有办法在构造时初始化结构,因此没有很好的方法来实现需要初始化的对象的值类型语义。 抱歉。 即使值类型语义更适合您的类型(例如,比某些人认为的更常见),如果需要初始化,则必须使用引用类型。 结构的延迟初始化并不真正起作用。 例如,如果有一个名为MyDict的Dictionary <String,MonthData>,则重复访问MyDict(“George”)。FrontLine将分别生成一个新List。 讨厌。

可变结构不是邪恶的; 如果有的话,我是他们更强大的倡导者之一。 尽管如此,.net处理可变结构存在一些限制,因此有许多情况下值类型语义是合适的,但.net限制使得无法正确提供这样的语义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM