Recently, while co-programming with colleagues, we started discussing the best ways to initialize new objects in C#. I've always implemented it using constructors, although he tends to static engineering methods. This has caused a lot of back and forth discussion about the pros and cons of each type.
To illustrate what I said, here are two examples:
// Using the constructor SqlConnection myConnection = new SqlConnection(connectionString); // Using a static factory method IDbConnection myConnection = (connectionString);
I've never considered implementing these static factory methods before, and I laughed at myself for not understanding what it is. Since then, I have changed my attention and let's dig into its pros and cons.
Advantages of static factory methods
No need to return a new instance
The constructor always returns a new object.
When new object creation fails, you cannot use a cached object or return null. Especially when writing library code, it may be flexible in the future.
You can use the method reference
If you tend to write C# in a practical way, you might appreciate the reference you can pass in your code that method (or formally called "method groups"). Compare:
// Static factory method - the method group can be passed in directly as a function reference var bars = () // Constructors - you have to pass in a lambda that constructs the instance via new. var bars = (f => new Bar(f));
There is no functional difference in this code, it is just a problem in the style of the code. Therefore, it may not be taken too seriously in decision-making.
You can understand by name
For some objects, especially objects that can be constructed in many similar ways, it can benefit greatly in the way objects are constructed. Let's take the Color class as an example, which can be constructed with CMYK and RGB parameters.
// With constructors var color = new Color(25, 25, 5, 80); var color = new Color(100, 150, 50); // With static factory methods var color = (25, 25, 5, 80); var color = (100, 150, 50);
Compare with a more descriptive static engineering approach, unless you know that the constructor of Color's four values is CMYK and the constructor of the three values is RGB, you can't distinguish it by reading the code.
I think if you have different ways of constructing objects, especially the ways in which parameters are similar to each other, there is a good reason to use the static factory method.
Factory methods can return different classes
new Foo()
Always return oneFoo
A new instance of the class,It's easy to return one
IFoo
interface, orFoo
a subclass of . A real example that might be related to it:
// This could create an IpV4IpAddress that implements IIpAddress IIpAddress ipv4Address = ("127.0.0.1"); // This could create an IpV6IpAddress that implements IIpAddress IIpAddress ipv6Address = ("2001:0db8:0a0b:12f0:0000:0000:0000:0001")
When providing a public API (for example in a library context), it can be valuable to be able to return different actual types based on input. Especially because this means you can hide some implementation details behind an interface or base class.
I'm not sure if the value in the application code is as great, where you can control the entire library code and make large-scale refactoring easier.
Things you shouldn't do in the constructor
Often, people don't expect constructors to do many other things besides constructing objects. You may do I/O, database access, etc. in the constructor, but most people don't expect it. By convention, you are free to perform more work in a static factory method without anyone taking notice.
Some people also don't think you should throw exceptions in the constructor. Maybe it depends on the language, but it's totally OK in C#, if you want to create unmanaged resources in the constructor, please note a few points.
Disadvantages of the static factory method
Things you shouldn't do in a constructor
By convention, constructors are usually simpler. When I call the constructor, I usually don't want it to perform I/O or
other. This greatly reduces the constructor flexibility, which is both a blessing and a curse.
Meaning more code
Anyway, you still need a constructor to actually construct the object. The static factory method is more code, and code is a responsibility in one place. It's usually not very copying code, and usually the static factory method isn't particularly long, so this may not be a big drawback.
It's hard to find
Usually, when I try to construct a new object, I look for the constructor first. It is difficult to find static methods with autocomplete functionality because they are usually not distinguishable from other static methods.
I think the biggest problem with static methods is that you lose discoverability.
After research and thinking, I think my current view is:
- You should always create a constructor that maps 1:1 to fields inside the class
- If you need to spend a lot of practice creating objects (such as IO), or be interested in caching objects and reusing them, use the static factory method.
- If you need API stability (for example for library development), hide the constructor and use the static factory method as it gives you the flexibility to implement.
- If you have a number of different ways to create classes, create static factory methods and use them as they provide descriptiveness for you.
The above is a detailed content on the advantages and disadvantages of C#'s static factory methods and constructors. For more information about C#'s static factory methods and constructors, please pay attention to my other related articles!