I was advised to change a List<string> property to a Collection<string>, in a base class, because it is more appropriate for inheritance.
This 'rule' was referred to: https://msdn.microsoft.com/en-us/library/ms182142.aspx
System.Collections.Generic.List is a generic collection that is
designed for performance and not inheritance.
System.Collections.Generic.List does not contain virtual members
that make it easier to change the behavior of an inherited class. The
following generic collections are designed for inheritance and should
be exposed instead of System.Collections.Generic.List.
System.Collections.ObjectModel.Collection<T>
System.Collections.ObjectModel.ReadOnlyCollection<T>
System.Collections.ObjectModel.KeyedCollection<TKey, TItem>
Does a similar rule apply to Dictionary<string, string>?
I ask because it is also in the System.Collections.Generic namespace. Or maybe I have misunderstood and the rule only applies to Lists.
BTW, the Dictionary purpose is to hold errors (in a similar format to ModelState). I am not currently sure at exactly what stage I will be adding errors to it.
If I should be avoiding Dictionary<string, string> in the base class, what should I be using in it's place?
I have come across KeyedCollection but not sure if that is a good replacement.
Dictionary<TKey, TValue> does not have any base class you can use instead of it. It may be better to use interface (IDictionary<TKey, TValue> or maybe IReadOnlyDictionary<TKey, TValue> -both implemented by Dictionary), but it depends on your needs.
Note that it is very hard to express whether property returns internal storage or clone (and hence what happens when caller changes object) - you may want to consider IEnumerable<T> or methods that hide dictionary as implementation details.
So basically what you were told could potentially be wrong for the use case you are going for.
The statement in the msdn article means by inheritance if you want to create your own implementation of a collection by deriving from it like so:
public class MyCollection : Collection<MyType>
The advantage of using Collection<T> in this scenario is that you can alter the behavior significantly as it exposes the following methods which can be overriden: ClearItems, InsertItem, RemoveItem and SetItem. When you derive from List<T> you can't override any methods at all (except for the standard ToString, Equals and GetHashCode).
But as you stated in your comment you use the List/Dictionary/Collection as a property. Therefore it rather depends on your own use case.
If you want deriving classes to just use the collection from the base class you can let it be whatever you think is best suited for your needs. But if you think that the deriving class will know better which collection to use then you should
pick an interface from the System.Collections.Generic namespace.
I won't tell you which types or interfaces you should use when as it heavily depends on which functionality you need.
And by the way: the KeyedCollection can only be used to create your own key value collection (it is abstract). Therefore having a KeyedCollection as a property would mean that you'd also need an implementaion of a KeyedCollection.
The other day i was looking at C# Boolean struct metadata.
Boolean implements the interface IConvertible. But looking at Boolean's members i could not see most of the IConvertible members.
I've done some tests with some colleagues, including creating our own classes, and came to the conclusion that IConvertible must be implemented explicitly for Boolean.
The question is, why are they not visible? I understand it might be a 'by design decision' but i understand that it would add greater value if they were visible to anyone inspecting the metadata.
The tests were done in VS2010 .NET4.0
The reason is that those methods are there just to implement the I-interface and not to augment the class' public interface.
What I mean is that if you have the following:
public class MyClass : IConvertible
{
// implementation
}
You might want MyClass to be convertible, indeed, so you can pass references of it to methods that expect IConvertible:
public void DoSomethingWithConvertible(IConvertible conv)
But you might not want variables of type MyClass to expose the Convert methods. You simply don't want MyClass's public interface to have that method, then you implement the interface explicitly. That's the whole idea of the approach. This means the following is not allowed:
MyClass a = new MyClass();
a.Convert();
However, the following is still be allowed:
MyClass a = new MyClass();
((IConvertible)a).Convert();
The whole idea behind this is that even though we're using the exact same instance, a as MyClass doesn't have the method. A as IConvertible does have the method. Think of it as if you're allowing the instance to have split personality.
Usually I end implementing every interface implicitly. However, there are very specific situations where I'd implementing them explicitly exactly for the reasons outlined above.
BTW, thanks for the great question!
Because explicit interface implementation actually hides the implementation.
The metadata does indeed show the explicitly implemented. Do you mean intellisense and not metadata?
I'd say that's by design and help the developer of say Boolean to restrict the interface to a subset. By restricting what's suggested to use it also becomes visible what's considered abnormal usage. E.g. it's generally not advised to view a Boolean value as a specific numeric value but in certain cases it's handy to be able to do that anyways.
IDictinary<T,K> is another example. It implements IEnumerable<KeyValuePair<T,K>> making it possible to iterate over all the pairs in the collection and ICollation<KeyValuePair<T,K>>. So you can call Add on the dictionary given a KeyValuePair but usually you should use Add(K, key, T Value)
Try inspecting the class with a tool that provides read access to metadata. ILDASM for one and you can indeed find metadata of the explicitly implemented methods.
They are explicitly implemented. You can find all implemented convertables here: http://msdn.microsoft.com/en-us/library/system.boolean.aspx
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.
I'm trying to derive from List and selectively turn the IsReadOnly property on and off. I was hoping that the Add/Remove/[] functions would honor this property, but they don't.
What's the right way of doing this?
My derived class has some additional properties, so I can't unfortunately just wrap the list in ReadOnlyCollection.
Use encapsulation instead of inheritance in this case.
You should just make your class implement IList<T>, and have a private List<T> variable.
You can pass through any functions you wish, but also can completely override them, change behavior, etc. This gives you complete control (at the expense of having many methods that does nothing but call this.List.method(...) ).
In general, I don't think it's a good idea to inherit from the BCL collection classes in any case. I prefer to make them an implementation detail internal in my class.
List<T> is by definition a mutable type. There's no way to make it read-only.
If you're making a derived class, you should probably be implementing IList<T> directly rather than subclassing List<T> anyway. This will give you full control over the implementation, allowing you to make it read-only if you wish.
You could call the "AsReadOnly" method on list which should return to you an IList instance that should honor that it is...err...read-only.
...OK, I just read your last sentence, my bad. In which case maybe you just want to implement the IList interface or any friend and just route most of the interface to a list you keep internally. Then you can build this behaviour. Even so, I would do a similar pattern, provide some "AsReadOnly" method that explicitly gives you something that is read-only.
I have read that private variables in a base class are technically inherited by child classes, but are not accessible.
If this is correct, why do we say they are inherited when presumably they can only be accessed by reflection?
Subclassing is about inheriting implementation; and fields are an implementation detail.
The fields are indeed present, and are available via reflection. But ultimately, it is the base-classes job to manage the state of those fields via any public/protected/etc members.
But ultimately - if a base-class declares a property (and field) for property Foo, then when you set that property the data has to go somewhere. The sub-class has to include all the fields from the base-class for it to make sense. This is also critical for field-based serialization frameworks (such as BinaryFormatter).
Private fields are inherited in the sense, that they take up space on the heap when allocated. However, the derived class cannot access them directly.
why do we say they are inherited...
Personally, I don't. I consider inheritance to include those things that you can access in a child class, not those things that are hidden.
I could see someone saying that to be clear that inheritance includes all elements up the chain, but it strikes me as overly pedantic and not especially useful.