【问题标题】:Should a c# class generate instances of itself?c# 类是否应该生成自身的实例?
【发布时间】:2008-11-02 00:18:43
【问题描述】:

我有一个定义 CallRate 类型的类。我需要通过从文件中读取数据来添加创建类的多个实例的能力。

我向我的类 CallRate 添加了一个静态方法,该方法返回 List<CallRate>。一个类可以通过调用自己的构造函数之一来生成自己的新实例吗?它有效,我只是想知道这样做是否正确。

List<CallRates> cr = CallRates.ProcessCallsFile(file);

【问题讨论】:

    标签: c# class-design


    【解决方案1】:

    从静态方法中获取自己的对象是完全可以的。

    例如

    其中一个点网库与您做的事情相同,

    XmlReadrer reader = XmlReader.Create(filepathString);
    

    【讨论】:

    • 如果我没记错的话,这被称为工厂模式,并且如前所述,这是完成该任务的一种完全可行的方法。我通常更喜欢将工厂与班级分开,但这在很大程度上取决于个人喜好。
    • 有两种工厂(在 GoF 书中):抽象工厂和工厂方法。提出的方法是工厂方法的一个例子。
    • 是的,确实是工厂模式。
    【解决方案2】:

    当然可以,在某些情况下甚至鼓励这样做。有几个design patterns that deal with object creation,其中有几个就是你所描述的。

    【讨论】:

      【解决方案3】:

      当我需要检查参数的有效性时,我经常使用这种模式。强烈建议不要从构造函数中抛出异常。从工厂方法来说还不错,或者你可以选择返回null。

      【讨论】:

        【解决方案4】:

        对我来说似乎很好。在其他语言中,您可能会编写一个函数,但在像 C# 这样的语言中,静态方法扮演了这个角色。

        【讨论】:

          【解决方案5】:

          没关系。您刚刚创建的内容类似于简单的工厂方法。您有一个创建类型的有效实例的静态方法。实际上,您的方法甚至不必是静态的,您仍然有有效的代码。有一种设计模式(原型)可以从现有对象创建新的有效对象。详情请见http://www.dofactory.com/Patterns/PatternPrototype.aspx

          【讨论】:

          • 我需要一个充分的理由来开始学习类设计模式。谢谢。
          【解决方案6】:

          当然,对于简单的解析(或类似)场景 - 我实际上更喜欢 factory method 成为课程的一部分。是的——它确实打破了SRP,但它满足了KISS——所以我称之为净赢。对于更大的应用程序或更复杂的解析例程 - 将其作为外部工厂类更有意义。

          对于您的特定情况,我可能更喜欢采用 IEnumerable 而不是文件名的方法 - 这仍然会为您提供解析逻辑,但允许简单的单元测试和“重用”。调用者可以很容易地将文件包装到 IEnumerable 中。

          【讨论】:

            【解决方案7】:

            工厂方法通常是一个很好的设计。当我用 C# 编写它们时,我称它们为“新”,因此:

            new MyClass()
            

            变成

            MyClass.New()
            

            简单来说它是这样实现的:

            class MyClass
            {
                public static MyClass New()
                {
                    return new MyClass();
                }
            }
            

            大多数情况下,当有附加条件时,我会这样做

            【讨论】:

            • 一定会让习惯VB.Net的人感到困惑。在 VB.Net 中,构造函数称为“New”。
            • 也许;或者也许它很有意义 - 将其视为静态 ctor 与实例 ctor 或其他东西。我真的不能说,因为我没有花太多时间在 VB.NET 程序员身上。
            【解决方案8】:

            我有时使用公共静态方法作为构造函数重载的替代方法。

            尤其是在单独依赖参数类型来指示要构造哪种对象并不好的情况下。

            【讨论】:

              【解决方案9】:

              我喜欢让静态方法返回实例,正如上面多次建议的那样。

              @Paul:别忘了在上面的评论打勾,你会发现这是最好的答案。

              【讨论】:

              • 对不起!每个人都给了我一些帮助,所以我全力以赴。我没有通过勾选并选择一个来消除蜱虫的声誉。 boneHead = 我;
              • 你可以通过第二次按下“up-ticks”来删除它们
              【解决方案10】:

              只是想指出 “通过调用自己的构造函数之一来生成自己的新实例”

              不是来自构造函数,而是来自静态方法。

              【讨论】:

              • 是的,但是我的静态方法正在调用它的构造函数之一......我现在实际上已经将它分解为它自己的类。谢谢。
              【解决方案11】:

              当我需要一个类的即时实现时,我通常会使用它。例如

                  public class Car
                  {
                      public static Car RedExpensiveCar = new Car("Red", 250000);
              
                      public Car()
                      {
              
                      }
              
                      public Car(string color, int price)
                      {
                          Color = color;
                          Price = price;
                      }
              
                      public string Color { get; set; }
                      public int Price { get; set; }
                  }
              

              有了这个,我就不需要在我的代码中记住或编写构造函数参数了。

              Car car = Car.RedExpensiveCar;
              

              【讨论】:

              • 请注意,在您的示例中,Car car = Car.RedExpensiveCar 不是创建新汽车。它总是返回相同的实例。更有问题的是,由于您使用的是公共字段,因此可以将其分配给: Car.RedExpensiveCar = new Car("Primer Brown", 75);
              • 一般来说更好的是 public static Car RedExpensiveCar { get { return new Car("Red", 250000); } }
              【解决方案12】:

              这样做是完全可以接受的。当我这样做时,我通常将类的真正构造函数设为私有,以便明确构造实例的唯一方法是通过静态方法。

              这在“构造”可能并不总是返回新实例的情况下非常有用。例如,您可能希望返回以前缓存的对象。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-09-23
                • 1970-01-01
                • 2011-06-30
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多