代码之家  ›  专栏  ›  技术社区  ›  Benny

C中的实例初始化策略#

  •  1
  • Benny  · 技术社区  · 15 年前

    为了让类实例正常工作,一些字段应该正确初始化,初始化这些字段的策略是什么,应该通过构造函数给出什么,应该通过属性给出什么?

    我的困惑是,如果构造函数需要一个长的参数列表,就很难使用,如果通过属性,我往往会忘记设置一些属性。

    最佳实践是什么?

    4 回复  |  直到 15 年前
        1
  •  2
  •   Noon Silk    15 年前

    你必须问问自己,如果你的班级需要创造那么多的东西,也许它做的太多了。这是一个迹象,表明您应该重新考虑您的设计,或者只是构造函数正在做多少“工作”。

    确实,您不应该能够创建一个状态无效的实例;因此,构造函数应该获取您需要的所有属性。 在里面 有效状态。

    在某种程度上,这取决于你的模型。例如,我使用的ORM让构造函数接受一个参数;一个ID,通过它可以加载所有其他属性。如果我必须把它们全部传进去(这真的是ORM的工作;设置这个对象),那会很烦人。所以从这个意义上说,你可以说你有一个“无效”的对象(没有设置属性)。但你错了,你实际拥有的是一个“空白”或“空白”的物体。这和无效的不同。

    所以仔细考虑一下你的对象“无效”的含义。如果其他方法接受了这个对象,并因为没有设置某个对象而引发异常,我会认为它是无效的。使用这个逻辑来确定构造函数中需要什么,以及以后可以设置什么(通过其他进程)。

        2
  •  2
  •   Andrew Hare    15 年前

    这始终是一个平衡行为-您不希望有需要许多参数的构造函数,但也不希望要求用户在对象处于有效状态之前设置许多属性。不幸的是,这里没有真正的指导,因为你必须运用你对当前形势的最佳判断。

    很多时候,您可能需要创建一个具有许多属性和许多可能的配置的复合类型(例如 System.Web.Page )复合类型倾向于使用很少或没有参数的简单构造函数,并且必须通过属性设置所有值。复合类型是由低级分解(或基元)类型组成的高级类型。

    分解类型往往更简单,包含更少的状态,并且可以通过其构造函数完全初始化。分解类型的示例有 System.String System.Int32 . 这些类型非常简单,往往是复合类型的构建基块。

    如果您的类型是一个分解类型,那么请尽量让使用者通过构造函数完全初始化该类型。如果您的类型是复合类型,那么最好提供参数很少或没有参数的简单构造函数,并要求使用者通过属性设置器配置实例。

        3
  •  1
  •   Thomas    15 年前

    既然.NET 3.5允许您在创建时设置任何属性,我通常将带有参数的任何构造函数限制在实例绝对必须在创建时具有值的情况下。实际上没有任何其他原因可以添加带有参数imo的构造函数重载。

        4
  •  1
  •   Dmytrii Nagirniak    15 年前

    我想最好是表演 验证 一般都会尝试 保留没有参数的构造函数 因为它通常是不同.NET库的需求。

    通过验证,您将不得不检查对象的有效性,但这是非常常见的事情。字里行间的东西:

    public interface IValidateable {
      IEnumerable<string> Validate();
    }
    
    public class Person : IValidateable {
        public string Title { get; set; }
        public string First { get; set; }
        public string Last { get; set; }
        public Address HomeAddress { get; set; }
    
        public Person() {
          HomeAddress = new Address();
        }
    
    
        public IEnumerable<string> Validate() {
          var errors = new List<string>();
          if (string.IsNullOrEmpty(First))
            errors.Add("First name is required.");
          // And so on...
          return errors;
        }    
    }
    
    // Usage
    var p1 = new Person();
    var p2 = new Person {
        First = "Dmitriy"
      };
    
    if (p1.Validate().Any()) {
      // Do something with invalid object
    }