c#类应该生成自己的实例吗?

时间:2008-11-02 00:18:44

标签: c# class-design

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

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

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

12 个答案:

答案 0 :(得分:20)

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

e.g。

其中一个点网库与你做的一样,

XmlReadrer reader = XmlReader.Create(filepathString);

答案 1 :(得分:5)

当然没关系,甚至在某些情况下也会受到鼓励。有几个design patterns that deal with object creation,其中一些只是你所描述的。

答案 2 :(得分:3)

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

答案 3 :(得分:2)

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

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

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

答案 6 :(得分:1)

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

new MyClass()

变为

MyClass.New()

平凡地实现了这样:

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

大多数情况下,当有关于是否实际创建类或仅返回null或是否返回MyClass或从中派生的内容的其他条件时,我会执行此操作。

答案 7 :(得分:1)

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

特别是在单独依赖参数类型来指示意图何种对象构造的情况下。

答案 8 :(得分:1)

我很喜欢使用静态方法返回实例,正如上面提到的那样。

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

答案 9 :(得分:1)

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

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

答案 10 :(得分:1)

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

    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;

答案 11 :(得分:0)

这样做是完全可以接受的。当我这样做时,我通常会将类的真正构造函数设为private,这样很明显构造实例的 only 方法是通过静态方法。

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