I have a c# struct where I need to forbid calling the no args constructor on it.
MyStruct a;
/// init a by members // OK
MyStruct b = MyStruct.Fact(args); // OK, inits by memebers
MyStruct s = new MyStruct(); // can't have that
I'm doing this mostly to force explicet values for all members as there are no valid default values and all members must have valid values.
In C++ this would be easy, add a private constructor but c# doesn't allow that.
Is there a way to prevent the above?
I really need to enforce using a factory so preventing all public constructor calls would work just as well.
Full discloser: to avoid a mono dependency, the c# app is being automatically translated to D where new Struct()
results in a pointer and this is mucking things up for me. However this question is relevant despite that so just ignore it.
C# does not allow a struct to declare a default, no-parameters, constructor. The reason for this constraint is to do with the fact that, unlike in C++, a C# struct is associated with value-type semantic and a value-type is not required to have a constructor.
struct can include constructors, constants, fields, methods, properties, indexers, operators, events & nested types. struct cannot include a parameterless constructor or a destructor. struct can implement interfaces, same as class. struct cannot inherit another structure or class, and it cannot be the base of a class.
Technically, a struct is like a class , so technically a struct would naturally benefit from having constructors and methods, like a class does.
The Factory Method pattern is generally used in the following situations: A class cannot anticipate the type of objects it needs to create beforehand. A class requires its subclasses to specify the objects it creates. You want to localize the logic to instantiate a complex object.
You can't. All structs have a public parameterless constructor by definition in C#. (In the CLR almost none of them do, but they can always act as if they have.) See this question for why you can't define your own parameterless constructors on structs (in C#, anyway).
In fact, you can prevent this statement if you're happy to write your value type in IL. I've just checked, and if you make sure that your value type only has a parameterless constructor, and make it internal, you won't be able to write MyStruct ms = new MyStruct();
But this doesn't prevent:
MyStruct[] array = new MyStruct[1];
MyStruct ms = array[0];
which works around the new restriction - so it doesn't really buy you anything. That's quite good really, as messing around in IL would be messy.
Are you sure you really want to be writing a struct in the first place? That's almost never a good idea.
You can't.
All values in a struct must be initialized at construction time, and there's no way to do that outside the constructor.
What exactly are you trying to accomplish by doing that? Structs are value types, so you'll get a "new" struct for most operations. It will be very difficult to enforce the sorts of constraints you'd use a factory for on a struct.
Anyone can create a struct at any time without calling a constructor, as long as they have access to the struct. Think about it this way:
If you create an array of objects with 1000 elements, they all get initialized to null, so no constructors are called.
With structs, there is no such thing as null. If you create an array with 1000 DateTime objects, they are all initialized to zero, which equals DateTime.Min. The designers of the runtime chose to make it so you could create an array of structs without calling the constructor N times--a performance hit many people wouldn't realize was there.
Your factory idea is a good one, though. Would it meet your needs to create an interface and expose that, but make the struct private or internal? That's about as close as you'll get.
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