【问题标题】:Is it possible to initialize an object that automatically returns a seed of its own type? [closed]是否可以初始化一个自动返回其自己类型的种子的对象? [关闭]
【发布时间】:2011-10-18 09:30:28
【问题描述】:

例如,我正在尝试初始化一个新人

var me = new Person();

但我只是想知道该初始化是否有可能自动返回种子?

我正在尝试将其添加到构造函数中,但我不知道如何?

public class Person
{
   public Person Person(){ return ...}
}

好吧,那真的行不通。谁能向我解释为什么它不起作用以及是否有其他方法可以做到这一点?

我可以进行对象初始化,但我只是想知道这是否可能??

【问题讨论】:

  • “种子”是什么意思?
  • 将函数名称更改为CreatePerson 并使其成为静态?这称为the Factory (method) pattern。或者只是在你的构造函数中做一些事情。不,除了调用构造函数(和基类构造函数)及其(它们的)胆量之外,你不能让new 做任何事情。除了你正在构造的对象之外,构造函数不会返回任何东西。不,你不能让它成为虚拟的。您可以为此使用一个单独的(可能是抽象的)工厂类。
  • 什么是种子,你到底想要完成什么?对象的初始化返回该类型的对象,无需为该类型创建构造函数..
  • @Jan 当然,但它需要知道从哪里获取数据,假设并非所有人都被称为Joe...
  • @MerlynMorgan-Graham:是的……你说得对。我忘记了。

标签: c# model constructor


【解决方案1】:

你可以创建一个静态方法(工厂)

var seededPerson = Person.CreateNew();

public class Person
{
  private Person() {}

  public static Person CreateNew()
  {
    return new Person() { Seed = 123; };
  }
}

【讨论】:

    【解决方案2】:

    构造函数初始化当前(新分配的)实例;而已。它不能返回任何东西。听起来你只想要一个工厂方法:

    public class Person
    {
       public static Person Create(){ return ...}
    }
    

    【讨论】:

      【解决方案3】:

      来自您的评论:

      自动将值添加到变量(在本例中为“me”)并填充实例化的对象.. 即:拥有 Person.Name = "Joe" 等......而无需我手动进行对象初始化或其他什么...... . 基本上我希望模型/类在我实例化它之后立即创建自己的数据..

      只需将实现添加到无参数构造函数:

      public class Person
      {
          public Person()
          {
              this.Name = "Joe";
          }
      
          public string Name { get; set; }
      }
      

      当您调用var me = new Person(); 时,Name 将已经被"Joe" 填充。

      构造函数的更多用法

      如果您希望能够更快地自定义名称,那么您可以向该构造函数添加参数,或者添加一个带参数的不同构造函数:

      public class Person
      {
          public Person()
              : this("Joe") // Calls the other constructor that takes a name...
          {
          }
      
          public Person(string name)
          {
              this.Name = name;
          }
      
          public string Name { get; set; }
      }
      
      var me = new Person(); // Joe
      var you = new Person("You");
      

      在最新的 .Net 中,您还可以使用这些参数的默认值来缩短代码:

      public class Person
      {
          public Person(string name = "Joe") // Will be "Joe" unless you say otherwise
          {
              this.Name = name;
          }
      
          public string Name { get; set; }
      }
      
      var me = new Person(); // Joe
      var you = new Person("You");
      

      【讨论】:

      • 正是我要找的那个!
      【解决方案4】:
      public class Person
      {
          protected Person()
          {
          }
      
          public static Person BuildPerson(out int seed)
          {
              var person = new Person();
              seed = RuntimeHelpers.GetHashCode(person);
              return person;
          }
      }
      

      你是说这个吗?使用基于静态方法的“代理”构造函数?

      public class Person
      {
          public Person(out int seed)
          {
              seed = RuntimeHelpers.GetHashCode(this);
          }
      }
      

      带有out 参数的构造函数?

      作为旁注,RuntimeHelpers.GetHashCode(object) 返回一个对象的伪唯一 ID。伪唯一,因为这些数字可以被 .NET 重用。始终提供唯一 ID 的更好“实现”是:

      public class Person
      {
          private static int seed;
      
          public Person(out int seed)
          {
              seed = Interlocked.Increment(ref Person.seed);
          }
      }
      

      使用Interlocked.Increment 使构造函数线程安全。

      【讨论】:

      • 使用new Random() 这样在循环分配时很可能会导致“我所有的随机数都相同”的问题。只是说'
      • 我知道...但我不知道什么是种子。实际上,这意味着“在接下来的几毫秒内生成的所有 Person 都会给出相同的种子”:-) 取决于 DateTime.Now/UtcNow 的精度
      • @MarcGravell 您如何看待 RuntimeHelpers.GetHashCode(this) 的使用? (记住数字可以重复使用......)......这是“让 this 逃离构造函数”好吗?
      • 不完全是我要问的,但这些是一些有趣的点。我一定会记住这个答案。
      • @xanatos 可能会很好地完成这项工作 - 但是,如果要求是随机化,那么在许多方面最好传入一个随机化器(使对于初学者来说,它是可测试的)。一个创造性的解决方案,虽然
      猜你喜欢
      • 2019-05-09
      • 2012-06-11
      • 2023-02-16
      • 2015-07-19
      • 2011-09-11
      • 1970-01-01
      • 2013-05-01
      • 2017-07-13
      • 1970-01-01
      相关资源
      最近更新 更多