Is there a way to initialize virtual automatic property without using a constructor ?
or should i just make a private field ?
Virtual or not, you need a constructor. Or it will have the default-value for it's type.
Because it is not good to call a virtual member in constructor
Correct, you will have to step carefully. The normal rules do apply. To be safe you would design your property so that it doesn't need initialization or only initialize it in derived constructors where either the class or the property is sealed.
Note that there will be plenty of cases where automatic properties makes little or no sense.
In the case of a virtual automatic property, I would say that the initialization part makes this a problem, and would remove the "automatic" part and create a backing field.
Of course, since base constructors are called before descendant constructors, if a base constructor initializes the property to the wrong value, a descendant constructor has a chance to rectify that before construction of the object is final.
Related
You can't pass this as an argument to a base constructor - see e.g., C# language specification section 10.10.1 Constructor initializers (last line on page).
I don't understand this limitation and would like to. In C#, as opposed to C++, the instance being constructed is already at its actual type and "everything works" (though of course not everything is initialized; I mean that virtual functions called in a derived class' constructor execute the derived class' methods). Base classes are allowed to call virtual methods on themselves even though the derived class' override will be executed and the derived class might not be ready for it; that's not ruled out. So what is the reason for this restriction?
(In C++ this is allowed for three reasons. First, the user or a derived class is supposed to know what he is doing. Second, the user of C++ is supposed to know what he is doing. And third, even if the user doesn't know what he is doing the C++ philosophy is to give him the rope he requires to hang himself, and then facilitate him when he ties the knot. I actually like that philosophy!)
What I'm trying to do, by the way, is construct properly initialized list members in a circularly-linked list. There's a base class Element with a field Link to point to the next element. There's a class Head which derives from Element, it'll be the distinguished sentinel for the start of the list plus have special behavior for the entire list. The constructor for Element takes the head of the list as argument, I want to write as follows to initialize elements and the head properly:
class Element {
protected Element link;
public Element(Element prior)
{
this.link = null;
prior.link = this;
}
};
class Head : Element {
public Head() : base(this) {}
};
(Before you complain that I should do this example differently my actual code is somewhat more complicated - a specialized sparse array - and I have my reasons.) I'm going to use a factory for Lists (and a factory method on Head for adding elements) to avoid this, which arguably is better design, but I'm puzzled that this other reasonable method is outlawed.
The design of C# and .NET is intended to give the base class control over its invariants. Once the base-class constructor has been completed, derived-class code, including derived-class constructors, is allowed to manipulate the base-class portion of the object in any way allowed by the base class. A derived class cannot do anything with the object under construction other than storing values to its own (derived-type) fields prior to the base-class constructor call, but a base class contract can in effect say "I'm going to call this virtual method during my constructor, and any legitimate derived class must be prepared to deal with that".
The design does pose some limitations. The worst IMHO is that there is no mechanism by which a base class can assert control of the construction process at any time after the derived-class construction code gets access to its constructor parameters.
C# evaluates field initialization expressions before chaining to the base constructor, on the theory that this will allow derived-class objects to set themselves up before the base constructor calls their virtual methods; a consequence of this is that field-initializer expressions can't do anything with the object under construction. VB.NET runs initializers after the base constructor, which allows more convenient access but means fields will be unitialized if the base constructor calls any virtual methods. Personally, I would regard the C# approach as "almost" useful, but the inability to handle classes whose invariants would be affected by constructor parameters severely limits its usefulness.
What I'd really like to see, btw, would be for Object to include a virtual method that will run between the time the most derived constructor finishes execution or throws an exception and the time control returns to the code that calls foo = new Bar();. The primary reason that base-class constructors expose the objects under construction before derived-class constructors get to run is that there is no standard way for them to ensure that they'll ever get control after that. Such a design would greatly improve constructor sequencing. I'm not holding my breath for such a thing, though.
XmlSerializer do not serialize readonly fields, readonly properties (only with getter), private fields etc. In addition it will not serialize the object if the class does not have a parameterless constructor. My questions:
AFAIK these problems arise because private (and readonly) fields can not be accessed (and changed) while deserializing. But what if I will not deserialize? Don't I have an option for this?
Because of the same reason (deserialization concerns), it does not serialize the object if the class does not have a parameterless constructor. But when I add a private parameterless constructor it works fine. How?
I do not like to add a parameterless constructor to every class, and make all fields public and non-readonly just to be able to serialize it. For now I am throwing an exception in the private parameterless constructor to prevent the usage. Is there an attribute for constructors which tells the compiler that only authorized calls can be made to that constructor? If not at least I would like to mark it with an attribute which throws the exception if it is called.
That's quite a good question, and I'll try my best to answer:
I believe the reason for the setter as well as the getter is that it's generally assumed if you've only got a getter, then it implies it's not an instance property, it's something that is derived. That would imply if you were to deserialize it (I know you're not doing this) then you could derive this value by setting all the other fields, and therefore serialization doesn't need to care about it.
The reason the parameterless constructor is required is because the type will be created using Reflection. Probably through a call like Activator.CreateInstace(type). This requires a parameterless constructor for the instance to be created, although it probably doesn't matter if it's public or private.
The reason the instance is required is so the fields on it can then be populated with the data retrieved from the XML.
You'll need this constructor, however you could add the ObsoleteAttribute to ensure that it's not called manually, or do as you're doing and make it private.
[Obsolete(true)]
public Foo()
{
}
One way of working around some of these issues may be to implement the IXmlSerializable interface manually, then you have a finer control over serialization but will still need that parameterless constructor.
I just read http://blog.gurock.com/articles/creating-custom-exceptions-in-dotnet/
I don't know when it is written. It says:
"Since C# unfortunately doesn’t inherit constructors of base classes, this new type only has the standard constructor with no parameters and is therefore relatively useless."
This says the same in 2010: C#: inheriting constructors
Is this still true?
EDIT: Following on from answers, I'm sure there would be a way around the default parameterless constructor. Are there other reasons for lack of constructor inheritance?
Constructors have never been inheritable in the entire lifetime of the C# language. That hasn't changed in C# 5.0: at the end of section 1.6.7.1 of the C# 5.0 spec, it still says:
Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.
So it still holds true today, and I imagine it will remain so in the foreseeable future.
You have to explicitly call the constructor of the base class, unless the base class defines a default constructor. So yes they are not inherited.
Which sometimes lead to a bunch of boiler plate code where you do nothing than pass arguments from one constructor to another
public class NegativArgument : Exception {
public NegativeArgument() : this("The number given was less than zero"){}
public NegativeArgument(string message) : this(message,null){}
public NegativeArgument(string message, Exception inner) : base:(message,inner){}
}
but what if you had an Exception type that should always have the same message? how would you solve that if the constructors were inherited? The exception class has a constructor that accepts a message so creating a new Exception type would in that case get that constructor too, not inheriting constructors makes it easy
public class NegativArgument : Exception {
public NegativeArgument() : base("The number given was less than zero"){}
}
If the base class does not have a default constructor you will have a compile error if you do not explicitly call a base class constructor.
Constructors are not inherited in C#.
If they were, then every class would have a default parameterless constructor (because all classes derive from Object and Object has a default parameterless constructor).
Many classes should only be constructed with specific values; this would be impossible to ensure if every class had a default parameterless constructor.
You should call them explicitly the constructor of the base classes. They are not inheritable.
Didn't change anything about them.
Check out : Constructors (C# Programming Guide)
From the spec §1.6.7.1:
Unlike other members, instance constructors are not inherited, and a
class has no instance constructors other than those actually declared
in the class. If no instance constructor is supplied for a class, then
an empty one with no parameters is automatically provided.
http://msdn.microsoft.com/en-us/library/ms228593.aspx
This answer is based upon the section "Constructors are not inherited" near the bottom of this entry on Jon Skeet's blog.
Summary
There are many cases in which a derived class may require information beyond that contained in the base class. Jon gives the example of the FileInfo class which requires additional information to be well-defined. Namely, that of the file for which info is to be provided
Any suggested 'fix' for this would entail overriding things in a way that prevents constructing such derived objects using the inherited constructors. However, knowingly requiring derived classes to override their base classes in a way that makes them more restrictive goes against best practice. (see: this question for Jon's discussion of the Liskov Substitution principle and the importance of being able to use derived classes wherever their base can be used.)
Additionally, from just a maintenance perspective, forcing manual override of constructors would make it difficult to reason about future behavior should the base class constructors change, and would entail having to always check, and often modify, any derived classes when new constructors are added to the base. Even a few of these would be problematic; but in cases where there are dozens or more such classes (and derived classes of those classes, etc.), maintenance and QA will quickly become a nightmare.
L2SQL generates entities with a default a parameterless constructor. This CANNOT be changed as it is needed to materialise the object.
However, if my object can only be created with certain values initialised how would I go about hiding the parameterless constructor so that a consumer only sees a constructor with parameters?
1) I can create another partial class of the same name and add my new constructor there but the consumer now simply has two options to create an instance of my class. The parameterless constructor is still visible.
2) Use interfaces. It is not possible to create an interface that defines constructors.
How do people approach this as it looks like an issue that would occur a lot.
If I understand you correctly, you want to prevent other users of the class from constructing one from the parameterless constructor, but still allow Linq2SQL to use it (as it must do so).
Luckily you are wrong when you say the default parameterless constructor cannot be changed. If you change the constructor of a Linq2SQL entity class to be private, then it will still be called by Linq2SQL as it uses reflection, and it is possible to call a private constructor if you use reflection. (Incidentally, other changes to the constructor can also be done with Linq2SQL).
Of course, the other users of the class can also use reflection to call that private constructor and create a class in a private state, but that is true of all .NET classes (and indeed applies elsewhere - e.g. it's often not hard to usurp the privacy of C++ classes, though there is no implementation-independent guarantee either way). But then it's pretty much always possible to use reflection to mess a class up; encapsulation is a mechanism to ensure correctness, not security. (But security restrictions on what code can use reflection then builds security on top of that less guarantee).
Am I the only person that wants this? It seems to be something that could reasonably have been provided for any class with a public parameterless constructor. Now having to instantiate these properties inside the constructor of the class that uses them somewhat obviates the convenience of automatic properties.
I would want to be able to specify the degree of thread safety required. In particular, do you need locking code to be emitted?
Indeed that might be useful, but it is what it is. There is no sign of this in C# 4.0, so you'll just have to use either a constructor or a field (and manual property implementation).
Re your "for any class with a public parameterless constructor" - actually, I'd assume that any implementation would be directly comparable to field initializers, so would work regardless of the constructor composition.