An answer in this question made me wonder about the .NET framework design choices.
The .NET framework has full support for Partial classes, interfaces, and methods. Is there a compelling reason that support for partial constructors was not added, in the same manner?
This seems like it would simplify class construction within partial classes. For example, form constructors built by a designer in Windows Forms could have the form construction code directly in the constructor, split into two files. Partial "Initialize()" methods seem to be a somewhat common pattern, which could be simplified in this case.
The only potential downside I can see would be the lack of determinism in the order of constructor calls, but in many cases, the ordering of the parts wouldn't matter. If it did, you could always avoid the partial constructor.
Being a middle-level language, C reduces the gap between the low-level and high-level languages. It can be used for writing operating systems as well as doing application level programming. Helps to understand the fundamentals of Computer Theories.
There is no need to learn C before learning C++. They are different languages. It is a common misconception that C++ is in some way dependent on C and not a fully specified language on its own. Just because C++ shares a lot of the same syntax and a lot of the same semantics, does not mean you need to learn C first.
Yes, C is a better choice for hardware-related projects, but the majority of developers work with web and mobile-related projects.
The only potential downside I can see would be the lack of determinism in the order of constructor calls, but in many cases, the ordering of the parts wouldn't matter. If it did, you could always avoid the partial constructor.
That part is more important to your question than it seems.
If you really want to understand how the C# language is put together, one thing you can do is follow Eric Lippert's blog. He works on the C# language for Microsoft, and talks a lot about choosing features with limited resources. Read his blog for a while and you'll start to get a sense of how features make it into the language.
One factor he's mentioned on a few occasions is whether or not there's already a trivial work-around for the problem the feature would solve. So going back to the quoted portion of your question, you bring up two important points:
Put those together and it's just not a winning feature.
I would vote yes, and I'll give a concrete example why.
Many technologies that emit code using a generator (Linq To SQL for example) will/must emit a default constructor. However, often I will also want to do things in a constructor, such as wiring up to one of the data events.
I can't do this without a partial constructor, since the default constructor is already tied up by the generated code, and I obviously don't want to alter the generated code to add my logic there.
Well, partial
classes and interfaces are another story. This concept would be comparable to partial
methods. They actually does nothing but to tell the compiler this method can exist somewhere and if it doesn't remove the method call. It doesn't allow introduction of a duplicate method.
Since a constructor is never called directly, it wouldn't make any sense to have such a concept. I believe the current initialize pattern works pretty well in most scenarios. Introducing another partial thing would unnecessarily make the language more complex without introducing significant benefits.
I would vote no. Mainly because you can accomplish the same thing with a partial method that you are trying to accomplish with a partial constructor without the non-determanism issue.
Instead of having a partical constructor, have the WinForms designer run in the constructor. At the end of the generated code the emit a partial method and call to UserConstructor. Users could then use this for their initialization.
You could even do bookended partial methods to satisfy all scenarios (BeginUserConstructor and EndUserConstructor).
Partial methods don't allow for defining multiple parts of the function's body in two seperate locations. It merely allows for a signature to exist in one file, and the implementation to optionally exist in the other. If the body never gets defined, references to the method are removed by the compiler.
Like Mehrdad said...with the constructor, you never really need that kind of functionality so it was never implemented.
I vote yes because I recently ran into a problem where having partial constructors is kind of needed.
However, I do entirely understand the problem regarding how they would be ordered.
After thinking over this problem for a few days I finally settled on a solution that might work well enough for my needs. It's Reflection, but still better than nothing.
// File1.cs
public partial class Example
{
public Example()
{
// Add code here to find & invoke methods with custom attribute "Initialize".
}
[AttributeUsage(AttributeTargets.Method)]
public class InitializeAttribute : Attribute
{
// Whatever you want here.
}
}
// File2.cs
partial class Example
{
[Initialize]
public void RandomMethod()
{
// This will be run automatically with a new instance of the object.
// It's just like it's part of the constructor.
// There is no limit to these. You can have lots of generated code pages.
}
}
There are a number of construction-related features I'd like to see, which would be helpful if combined with partial constructors; I'm not sure how useful partial constructors would be without them.
If a certain fields will be set when an object is created, and never modified thereafter, it seems much cleaner to combine the initialization and declaration, than to require that the the fields be declared in one part of the code and then initialized somewhere else. Further, the above features if combined would allow a class to initialize fields that depend upon constructor parameters before the base class constructor is called--something which is otherwise not possible.
Given the above features, I would favor a kind of parameterless partial constructors which would be bound to fields or groups of field, such that the fields could specify that they would only be written within the indicated partial constructor (a behavior even stricter than readonly
). If the value of a field will be invariant throughout the lifetime of a class object, attaching its initialization logic to the field would make that much clearer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With