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.
Why are virtual, abstract and override keywords not valid for Static function? What's the logic behind it?
Polymorphism via virtual dispatch is done by using the actual runtime type of the target instance, i.e. what the actual obj is in obj.Bar(...args...). Now: if you don't have a obj. instance, it makes no sense to discuss polymorphism.
Static methods are invoked with static-call, not virtual-call; the decision on what method to call is made entirely at compile time. There is no decision left to make. It comes down to the SomeType in SomeType.SomeMethod(...args...). You can of course still call between methods in a virtual method - you still have access to SomeBaseType.SomeOtherStaticMethod(...).
There are, in fact, languages out there that extend the polymorphism concept to static methods. C# isn't one of those languages, though. You are not allowed to call static functions through some kind of class reference, so you don't actually have a chance to do anything "polymorphic" there.
A static method is only really part of a particular class as a placeholder for the method. Static functions do not share lifetime or scope with the class they are declared in, and they are not really part of the object model.
These keywords (abstract, virtual, override) are related to an inheritance model and would have no meaning in a static context.
You shouldn't be accessing static methods through an instance. When you do, C# doesn't care about what type of object is in your variable; it goes by the type of the variable. That is, MyType obj = null; obj.StaticMethod(); works, because the object is never consulted. Scratch all that; in my version of Visual Studio, with default settings, you aren't even allowed to use a static method via an instance. Either way, that means virtual static wouldn't do anything worthwhile; virtual and override work by consulting the object to decide what method to use, and with static, you only have the type (which is effectively hard-coded, and thus rather useless with polymorphism). abstract being basically "requires an override in your class", it's not useful either.
I guess it wouldn't have been hard for the C# people to let you pretend static stuff could be overridden...but it can't. In order to call it, you have to specify the type (explicitly like MyType.StaticMethod(), or implicitly as mentioned above). They opted to make it clear that you can't have virtual static methods and have it work like you're expecting, by making it so you can't do it at all.
The keywords virtual, abstract and override are used with methods that are inherited. Static methods aren't inherited.
why "data members" should be declared "protected"?what can be the possible benifits?
Protected members are accessible by subclasses, which is not the case if you declare them private.
You declare things to be private or protected to hide them, so that only relevant things which are supposed to be used by the external world are exposed.
If you want to know why whould you want to hide members from the external world, you should get a book about object oriented probramming, because those are basic concepts.
protected simply means that subclasses are able to see that member, but the member is not part of the public API to the object.
Re the question; it depends what you mean by "data members". If you mean fields, then IMO they shouldn't be. It is fairly common to make some state (properties) protected, if subclasses would need that info (in particular methods), but it isn't necessary for the outside world.
A better example, however, is protected virtual, where the inheritor is able to change the implementation of an otherwise private (to the outside world) member. The classic example being:
protected virtual OnSomeMemberChanging(...) {}
protected virtual OnSomeMemberChanged(...) {}
where the inheritor can now react (or even block) changes to key values by using override to change the implementation (commonly but not always calling base.Whatever() at some point to invoke the original implementation as well).
From MSDN
The type or member can be accessed only by code in the same class or struct, or in a class that is derived from that class.
Possible benefits: You restrict the access to the class and its immediate childrens
I’ve been pondering about the C# and CIL type system today and I’ve started to wonder why static classes are considered classes. There are many ways in which they are not really classes:
A “normal” class can contain non-static members, a static class can’t. In this respect, a class is more similar to a struct than it is to a static class, and yet structs have a separate name.
You can have a reference to an instance of a “normal” class, but not a static class (despite it being considered a “reference type”). In this respect, a class is more similar to an interface than it is to a static class, and yet interfaces have a separate name.
The name of a static class can never be used in any place where a type name would normally fit: you can’t declare a variable of this type, you can’t use it as a base type, and you can’t use it as a generic type parameter. In this respect, static classes are somewhat more like namespaces.
A “normal” class can implement interfaces. Once again, that makes classes more similar to structs than to static classes.
A “normal” class can inherit from another class.
It is also bizarre that static classes are considered to derive from System.Object. Although this allows them to “inherit” the static methods Equals and ReferenceEquals, the purpose of that inheritance is questionable as you would call those methods on object anyway. C# even allows you to specify that useless inheritance explicitly on static classes, but not on interfaces or structs, where the implicit derivation from object and System.ValueType, respectively, actually has a purpose.
Regarding the subset-of-features argument: Static classes have a subset of the features of classes, but they also have a subset of the features of structs. All of the things that make a class distinct from the other kinds of type, do not seem to apply to static classes.
Regarding the typeof argument: Making a static class into a new and different kind of type does not preclude it from being used in typeof.
Given the sheer oddity of static classes, and the scarcity of similarities between them and “normal” classes, shouldn’t they have been made into a separate kind of type instead of a special kind of class?
It's a class as far as the CLR is concerned. It's just syntactic sugar in the C# compiler, basically.
I don't think there would be any benefit in adding a different name here - they behave mostly like classes which just have static methods and can't be constructed, which is usually the kind of class which became a static class when we moved from C# 1 to C# 2.
Bear in mind that if you want to create a new name for it, that probably means a new keyword too...
Your question is "why do I have to type the words static class X rather than foobar X". The answer is, because programmers already associate the word 'class' with 'a bundle of tightly packed encapsulated functionality someone wrote for me'. Which, coincidentally, fits perfectly with the definition of static classes.
They could've used namespaces instead, yes. That's what happens in C++. But the term 'static class' has an advantage here: it implies a smaller and much more tightly coupled group of functionality. For example, you can have a namespace called Qt or boost::asio but a static class called StringUtils or KWindowSystem (to borrow one from KDE).
Yes, they are very odd. They do have some class-like behavior, like being able to have (static) member variables, and restricting access to members using public/private.
I almost typed "public/protected/private" there, but obviously protected doesn't make sense, because there is no method inheritance of static classes. I think the main reason for this is that because there are no instances, you can't have polymorphism, but that is not really the only reason for inheritance. Polymorphism is great, but sometimes you just want to borrow most of the functionality of the base class and add a few things of your own. Because of this, sometimes you'll see static classes switched to use singleton patterns, just so that it can leverage the some functions from base set of classes. In my opinion this is a hacky attempt to close that gap, and it gets confusing and introduces a lot of unnatural complexity. The other option is aggregation, where the child class methods just pass calls through to the parent class methods, but this is requires a lot of code to stich it all together and isn't really a perfect solution either.
These days, static classes are usually just used as a replacement for global methods, i.e. methods that just provide functionality without being bound to an instance of anything. The OO purists hate any concept of a free/global anything floating around, but you also don't want to have to have an unnecessary instance and object floating around if you just need functionality, so a static "class" provides a middle-ground compromise that both sides can sort of agree with.
So yes, static classes are weird. Ideally, it would be nice if they could be broken into their own concept that provided the flexibility and lightweight ease-of-use that you get from methods that don't need to be bound to an instance (which we have now with static classes), and also group those methods into containers (which we also have now), but also provide the ability to define a base entity from which it will inherit methods (this is the part that is missing now). Also, it would be great it was a seperate concept from classes, for exactly the reasons you raise, it just gets confusing because people naturally expect classes to be instances with properties and methods that can be created and destroyed.
I don't know if this qualifies as an answer, but I would point out that "static classes" are more of a language concept and less of a CLR concept. From the point of view of the CLR, they are just classes, like any other. It's up to the language to enforce all the rules you described.
As such, one advantage of the current implementation is that it does not add further complexity to the CLR, which all CLR-targeting languages would have to understand and model.
Sure, they could have been made into a separate kind of thing.
But that would have required additional work in the CLR, the BCL, and across the language teams, and I that would have left other, more important things undone.
From a purely aesthetic point of view, I might agree with you.
Good point, it's probably because of historic reasons, i.e. they didn't want to invent something new as static classes already existed.
C++, Pascal (Delphi) and Java all have static classes, and those are what C# is based on.
Static classes and "normal" classes (and structs) are containers for executable code (members fields, properties, methods) and they declare a Type. If they had a separate word for this then we would ask the opposite ("if they are so similar, why did you not use the kayword class?").
I'd suggest "CLR via C#", where it's well explained how type resolving, method calling, etc occurs. It works in the same way for "both" classes, just instance members have additional parameter passed in for the instance object.
Classes are not like namespaces because they are only for naming and referencing. They do not affect the functionality of the class.
Classes are also different from interfaces, because interfaces are merely compile-time verification tools and do not have functionality of their own.
In my opinion, static classes are considered so because they can embed private fields, public properties and methods, though they are static, and have a fixed address location where each call to the singleton method or property will have its reference.
A structure is more likely a value type as when you write:
var struct1 = new Struct1();
var struct2 = struct1;
each of the properties will have been copied into a new memory location. Furthermore, with a structure, you will be able to change struct2.Property1 value without having it changed within struct1.Property1.
Per opposition, classes are in my understanding reference types, as when you write:
var class1 = new Class1();
var class2 = class1;
Here, the reference is copied. This means that when you change class2.Property1, this same property will also change in class1.Property1. This is because both classes points to the same memory address.
As for static classes, they are considered as reference types as when you change a StaticClass.Property value within a method, this change will get populated everywhere you reference this class. It has only one memory address and can't be copied, so that when another method or property call will occur, this new value will prevail over the old one. Static classes are meant to be shareable accross an entire application, so only one reference for it exists within your application. Therefore making them behave like a class.
A static class, even though singleton pattern is not, I guess, encouraged except for absolute purpose, could represent a real-life object just like a class or an instance of a class. However, since unique-in-the-world-objects seem to be rare enough, we don't really need them to represent a practical object, but merely some logical ones instead, such as tools and so forth, or some other costy-to-instiate objects.
EDIT
In fact, a static class is so similar to a class that in Visual Basic, there is no static class, but only a class with static (Shared in Visual Basic) members. The only point to consider is to make this class NotInheritable (sealed in C#). So, C# provides a more implicit functionality by allowing to declare a class static, instead of making it sealed, with an empty default constructor, etc. This is some kind of a shortcut, or syntaxic sugar, like we like to say.
In conclusion, I don't think there would be any benefit or gain having a new keyword for it.
Although class types, value types, and interfaces behave in many regards as though they are in three different kinds of things, they are in fact all described using the same kind of Type object; the parentage of a type determines which kind of thing it is. In particular, all types in .NET are class types except for the following:
Types other than System.Object which inherit from null; those are interfaces.
Types other than System.ValueType or System.Enum which inherit from System.ValueType or System.Enum; those are value types.
A few types like pointers and byrefs, which may be identified by Type objects (necessary for things like parameter types) but don't have members the way other types do.
Every type which has members, and whose parentage does not meet either of the above criteria, is considered to be a class. Static classes aren't really classes because of any particular quality they have, but rather because they don't have any quality that would make them be some other named kind of thing, and calling them "static classes" seems easier than inventing some other term to describe them.
What about static constructors? I think this is another important aspect to consider in your comparison. Classes and structs support them but interfaces and namespaces do not.
Construction implies instantiation. While the implementation may not actually create an "instance" of a static class, you could view static classes as a singleton instance of a class, to which there can only ever be one reference (the typename itself). If you could inherit static classes, you would break the singleton notion. If you could declare variables of the type, you might expect them to be cleaned up by the garbage collector when they are no longer referenced.
Why are they classes instead of structs? When I think of structs (value types), I think about values on the stack. Their existence is (typically) very short and they are copied frequently. This again breaks the single reference singleton notion above.
Does C# have the notion of private / protected inheritance, and if not, why?
C++
class Foo : private Bar {
public:
...
};
C#
public abstract NServlet class : private System.Web.UI.Page
{
// error "type expected"
}
I am implementing a "servlet like" concept in an .aspx page and I don't want the concrete class to have the ability to see the internals of the System.Web.UI.Page base.
C# allows public inheritance only. C++ allowed all three kinds. Public inheritance implied an "IS-A" type of relationship, and private inheritance implied a "Is-Implemented-In-Terms-Of" kind of relationship. Since layering (or composition) accomplished this in an arguably simpler fashion, private inheritance was only used when absolutely required by protected members or virtual functions required it - according to Scott Meyers in Effective C++, Item 42.
My guess would be that the authors of C# did not feel this additional method of implementing one class in terms of another was necessary.
No it doesn't. What would the benefit be of allowing this type of restriction?
Private and protected inheritance is good for encapsulation (information hiding). Protected* inheritance is supported in C++, although it isn’t in Java. Here’s an example from my project where it would be useful.
There is a base class in as 3rd party framework**. It has dozens of settings plus properties and methods for manipulating them. The base class doesn’t make a lot of checking when individual settings are assigned, but it will generate an exception later if it encounters an unacceptable combination.
I’m making a child class with methods for assigning these settings (e.g. example, assigning carefully crafted settings from a file). It would be nice to deny the rest of the code (outside my child class) the ability to manipulate individual settings and mess them up.
That said, I think in C++ (which, again, supports private and protected inheritance) it's possible to cast the child class up to parent and get access to parent's public members. (See also Chris Karcher's post) Still, protected inheritance improves information hiding. If members of a class B1 need to be truly hidden within other classes C1 and C2, it can be arranged by making a protected variable of a class B1 within C1 and C2. Protected instance of B1 will be available to children of C1 and C2. Of course, this approach by itself doesn't provide polymorphism between C1 and C2. But polymorphism can be added (if desired) by inheriting C1 and C2 from a common interface I1.
*** For brevity will use "protected" instead of "private and protected".
** National Instruments Measurement Studio in my case.
Nick
You can hide inherited APIs from being publicly visible by declaring that same member in your class as private, and using the new keyword. See Hiding through Inheritance from MSDN.
If you want the NServlet class to not know anything about the Page, you should look into using the Adapter pattern. Write a page that will host an instance of the NServlet class. Depending on what exactly you're doing, you could then write a wide array of classes that only know about the base class NServlet without having to pollute your API with asp.net page members.
#bdukes:
Keep in mind that you aren't truly hiding the member. E.g.:
class Base
{
public void F() {}
}
class Derived : Base
{
new private void F() {}
}
Base o = new Derived();
o.F(); // works
But this accomplishes the same as private inheritance in C++, which is what the questioner wanted.
No, public inheritance only.
You probably want a ServletContainer class that gets hooked up with a NServlet implementation. In my book, not allowing private / protected inheritance is not really a big deal and keeps the language less confusing - with LINQ etc. we allready have enough stuff to remember.
I know this is an old question, but I've run into this issue several times while writing C#, and I want to know...why not just use an interface?
When you create your subclass of the 3rd party framework's class, also have it implement a public interface. Then define that interface to include only the methods that you want the client to access. Then, when the client requests an instance of that class, give them an instance of that interface instead.
That seems to be the C#-accepted way of doing these sorts of things.
The first time I did this was when I realized that the C# standard library didn't have a read-only variant of a dictionary. I wanted to provide access to a dictionary, but didn't want to give the client the ability to change items in the dictionary. So I defined a "class DictionaryEx<K,V,IV> : Dictionary<K,V>, IReadOnlyDictionary<K,IV> where V : IV" where K is the key type, V is the real value type, and IV is an interface to the V type that prevents changes. The implementation of DictionaryEx was mostly straightforward; the only difficult part was creating a ReadOnlyEnumerator class, but even that didn't take very long.
The only drawback I can see to this approach is if the client tries to dynamically cast your public interface to the related subclass. To stop this, make your class internal. If your client casts your public interface to the original base class, I think it'd be pretty clear to them that they're taking their life in their own hands. :-)
First solution:
protected internal acts as public in the same assembly and protected on other assemblies.
You would need to change the access modifier of each members of the class which are not to be exposed through inheritance.
It is a bit restrictive though that this solution requires and forces the class to be inherited to be used by another assembly. Thus the choice of being used only by inheritance or not is taken by the unknowing parent... normally the children are more knowing of the architecture...
Not a perfect solution but might be a better alternative to adding an interface to hide methods and still leaving the possibility of using the parent methods to be hidden though the child class because you might not easily be able to force the use of the interface.
Problem:
The protected and private access modifiers cannot be used for methods that are implementing interfaces. That means that the protected internal solution cannot be used for interface implemented methods. This is a big restriction.
Final solution:
I fell back to the interface solution to hide methods.
The problem with it was to be able to force the use of the interface so that members to be hidden are ALWAYS hidden and then definitely avoiding mistakes.
To force using only the interface, just make the constructors protected and add a static method for construction (I named it New). This static New method is in fact a factory function and it returns the interface. So the rest of the code has to use the interface only!
No it doesn't. What would the benefit be of allowing this type of restriction?