Immutability/Read-only semantics (particular C# IReadOnlyCollection<T>) - c#

I am doubting my understanding of the System.Collection.Generic.IReadOnlyCollection<T> semantics and doubting how to design using concepts like read-only and immutable. Let me describe the two natures I'm doubting between by using the documentation , which states
Represents a strongly-typed, read-only collection of elements.
Depending on whether I stress the words 'Represents' or 'read-only' (when pronouncing in my head, or out loud if that's your style) I feel like the sentence changes meaning:
When I stress 'read-only', the documentation defines in my opinion observational immutability (a term used in Eric Lippert's article), meaning that an implementation of the interface may do as it pleases as long as no mutations are visible publicly†.
When I stress 'Represents', the documentation defines (in my opinion, again) an immutable facade (again described in Eric Lippert's article), which is a weaker form, where mutations may be possible, but just cannot be made by the user. For example, a property of type IReadOnlyCollection<T> makes clear to the user (i.e. someone that codes against the declaring type) that he may not modify this collection. However, it is ambiguous in whether the declaring type itself may modify the collection.
For the sake of completeness: The interface doesn't carry any semantics other than the that carries by the signatures of its members. In this case the observational or facade immutability is implementation dependent (not just implementation-of the-interface-dependent, but instance-dependent).
The first option is actually my preferred interpretation, although this contract can easily be broken, e.g. by constructing a ReadOnlyCollection<T> from an array of T's and then setting a value into the wrapper array.
The BCL has excellent interfaces for facade immutability, such as IReadOnlyCollection<T>, IReadOnlyList<T> and perhaps even IEnumerable<T>, etc. However, I find observational immutability also useful and as far as I know, there aren't any interfaces in the BCL carring this meaning (please point them out to me if I'm wrong). It makes sense that these don't exist, because this form of immutability cannot be enforced by an interface declaration, only by implementers (an interface could carry the semantics though, as I'll show below). Aside: I'd love to have this ability in a future C# version!
Example: (may be skipped) I frequently have to implement a method that gets as argument a collection which is used by another thread as well, but the method requires the collection not to be modified during its execution and I therefore declare the parameter to be of type IReadOnlyCollection<T> and give myself a pat on the back thinking that I've met the requirements. Wrong... To a caller that signature looks like as if the method promises not to change the collection, nothing else, and if the caller takes the second interpretation of the documentation (facade) he might just think mutation is allowed and the method in question is resistant to that. Although there are other more conventional solutions for this example, I hope you see that this problem can be a practical problem, in particular when others are using your code (or future-you for that matter).
So now to my actual problem (which triggered doubting the existing interfaces semantics):
I would like to use observational immutability and facade immutability and distinguish between them. Two options I thought of are:
Use the BCL interfaces and document each time whether it is observational or just facade immutability. Disadvantage: Users using such code will only consult documentation when it's already too late, namely when a bug has been found. I want to lead them into the pit of success; documentation cannot do that). Also, I find this kind of semantics important enough to be visible in the type system rather than solely in documentation.
Define interfaces that carry the observational immutability semantics explicitly, like IImmutableCollection<T> : IReadOnlyCollection<T> { } and IImmutableList<T> : IReadOnlyList<T> { }. Note that the interfaces don't have any members except for the inherited ones. The purpose of these interfaces would be to solely say "Even the declaring type won't change me!"‡ I specifically said "won't" here as opposed to "can't". Herein lies a disadvantage: an evil (or erroneous, to stay polite) implementer isn't prevented from breaking this contract by the compiler or anything really. The advantage however is that a programmer who chose to implement this interface rather than the one it directly inherits from, is most likely aware of the extra message sent by this interface, because the programmer is aware of the existence of this interface, and is thereby likely to implement it accordingly.
I'm thinking of going with the second option but am afraid it has design issues comparable to those of delegate types (which were invented to carry semantic information over their semanticless counterparts Func and Action) and somehow that failed, see e.g. here.
I would like to know if you've encountered/discussed this problem as well, or whether I'm just quibbling about semantics too much and should just accept the existing interfaces and whether I'm just unaware of existing solutions in the BCL. Any design issues like those mentioned above would be helpful. But I am particularly interested in other solutions you might (have) come up with to my problem (which is in a nutshell distinguishing observational and facade immutability in both declaration and usage).
Thank you in advance.
† I'm ignoring mutations of the fields etc on the elements of the collection.
‡ This is valid for the example I gave earlier, but the statement is actually broader. For instance any declaring method won't change it, or a parameter of such a type conveys that the method can expects the collection not to change during its execution (which is different from saying that the method cannot change the collection, which is the only statement one can make with existing interfaces), and probably many others.

An interface cannot ensure immutability. A word in the name wont prevent mutability, that's just another hint like documentation.
If you want an immutable object, require a concrete type that is immutable. In c#, immutability is implementation-dependant and not visible in an interface.
As Chris said, you can find existing implementations of immutable collections.

Related

Is object casting an inevitability of reality when there is a need to design modular architecture?

It is common to read around that object casting is a bad practice and should be avoided, for instance Why should casting be avoided? question has gotten some answers with great arguments:
By Jerry Coffin:
Looking at things more generally, the situation's pretty simple (at
least IMO): a cast (obviously enough) means you're converting
something from one type to another. When/if you do that, it raises the
question "Why?" If you really want something to be a particular type,
why didn't you define it to be that type to start with? That's not to
say there's never a reason to do such a conversion, but anytime it
happens, it should prompt the question of whether you could re-design
the code so the correct type was used throughout.
By Eric Lippert:
Both kinds of casts are red flags. The first kind of cast
raises the question "why exactly is it that the developer knows
something that the compiler doesn't?" If you are in that situation
then the better thing to do is usually to change the program so that
the compiler does have a handle on reality. Then you don't need the
cast; the analysis is done at compile time.
The second kind of cast raises the question "why isn't the operation
being done in the target data type in the first place?" If you need
a result in ints then why are you holding a double in the first
place? Shouldn't you be holding an int?
Moving on to my question, recently I have started to look into the source code of the well known open source project AutoFixture originally devloped by Mark Seemann which I really appreciate.
One of the main components of the library is the interface ISpecimenBuilder which define an somehow abstract method:
object Create(object request, ISpecimenContext context);
As you can see request parameter type is object and by such it accepts completely different types, different implementations of the interface treat different requests by their runtime type, checking if it is something they cable dealing with otherwise returning some kind of no response representation.
It seems that the design of the interface does not adhere to the "good practice" that object casting should be used sparsely.
I was thinking to myself if there is a better way to design this contract in a way that defeats all the casting but couldn't find any solution.
Obviously the object parameter could be replaced with some marker interface but it will not save us the casting problem, I have also thought that it is possible to use some variation of visitor pattern as described here but it does not seem to be very scalable, the visitor will must have dozens of different methods since there is so many different implementations of the interface that capable dealing with different types of requests.
Although the fact that I basically agree with the arguments against using casting as part of a good design in this specific scenario it seems as not only the best option but also the only realistic one.
To sum up, is object casting and a very general contracts are inevitability of reality when there is a need to design modular and extendable architecture?
I don't think that I can answer this question generally, for any type of application or framework, but I can offer an answer that specifically talks about AutoFixture, as well as offer some speculation about other usage scenarios.
If I had to write AutoFixture from scratch today, there's certainly things I'd do differently. Particularly, I wouldn't design the day-to-day API around something like ISpecimenBuilder. Rather, I'd design the data manipulation API around the concept of functors and monads, as outlined here.
This design is based entirely on generics, but it does require statically typed building blocks (also described in the article) known at compile time.
This is closely related to how something like QuickCheck works. When you write QuickCheck-based tests, you must supply generators for all of your own custom types. Haskell doesn't support run-time casting of values, but instead relies exclusively on generics and some compile-time automation. Granted, Haskell's generics are more powerful than C#'s, so you can't necessarily transfer the knowledge gained from Haskell to C#. It does suggest, however, that it's possible to write code entirely without relying on run-time casting.
AutoFixture does, however, support user-defined types without the need for the user to write custom generators. It does this via .NET Reflection. In .NET, the Reflection API is untyped; all the methods for generating objects and invoking members take object as input and return object as output.
Any application, library, or framework based on Reflection will have to perform some run-time casting. I don't see how to get around that.
Would it be possible to write data generators without Reflection? I haven't tried the following, but perhaps one could adopt a strategy where one would write 'the code' for a data generator directly in IL and use Reflection emit to dynamically compile an in-memory assembly that contains the generators.
This is a bit like how the Hiro container works, IIRC. I suppose that one could design other types of general-purpose frameworks around this concept, but I rarely see it done in .NET.

semantically represent generics

I am trying to understand generics in a semantic way. For instance, abstract classes seemed to snap into place for me when I read people refer to them as structures that can set policy. Interfaces snapped when I read people refer to them as collaboration contracts.
What are some good ways to think about generics that might help me to differentiate them from other OO structures and write more intelligent APIs?
Think of generic classes as stencils to make other classes (similarly, generic functions are stencils for making other functions). Type parameters serve as openings in your stencils: by plugging in a concrete type into them, you make the generic class or the generic function into a real class or function. The type parameters "stick through" the designated holes in the stencil, producing a complete definition.
It seems you want to approach your understanding from a top-down perspective. "What is it" in a qualitative sense and then derive the real meaning from there. Isn't it easier to simply learn what these different constructs do rather than trying to come up with labels? i.e. approach it from a bottom-up perspective and infer your own qualitative descriptions from what you've now already understood firsthand.
Abstract classes require you to implement a property or method and can't be instantiated. What distinguishes it from an interface? It requires subclasses to choose yours as its only base class. Interfaces face no such restriction but require you to define its entire behavior in the implementation, rather than relying on some of the behavior to be defined in the base class.
Similarly, generics allow you to introduce types as variables that can be specified by the caller. The utility of this is analogous to method parameters in general, just taken to a higher level. In other words, method parameters allow you to vary the implementation based on some input specified by the caller. Generic parameters allow you to vary the implementation based on some (other) input (i.e. types) specified by the caller.
Surely it's clear why List<T> is more useful than ArrayList. I'm not really sure why metaphors are really helpful for understanding why.
You could view them as wrappers around object types. You are creating functions that will do something for whatever type of object it is instantiated for, so it's like a template that will perform the same work for multiple types of objects.
Microsoft's introduction to generics might have some good descriptions as well
http://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx

What is the benefit of using type-safe collection classes?

I was wondering, why on some occasions i see a class representing some type's collection.
For example:
In Microsoft XNA Framework: TextureCollection, TouchCollection, etc.
Also other classes in the .NET framework itself, ending with Collection.
Why is it designed this way? what are the benefits for doing it this way and not as a generic type collection, like was introduced in C# 2.0 ?
Thanks
The examples you gave are good ones. TextureCollection is sealed and has no public constructor, only an internal one. TouchCollection implements IList<TouchLocation>, similar to the way List<T> implements IList<T>. Generics at work here btw, the upvoted answer isn't correct.
TextureCollection is intentionally crippled, it makes sure that you can never create an instance of it. Only secret knowledge about textures can fill this collection, a List<> wouldn't suffice since it cannot be initialized with that secret knowledge that makes the indexer work. Nor does the class need to be generic, it only knows about Texture class instances.
The TouchCollection is similarly specialized. The Add() method throws a NotSupportedException. This cannot be done with a regular List<> class, its Add() method isn't virtual so cannot be overridden to throw the exception.
This is not unusual.
In the .NET framework itself, many type-safe collections predate 2.0 Generics, and are kept for compatibility.
For several XAML-related contexts, there's either no syntax to specify a generic class, or the syntax is cumbersome. Therefore, when List<T> wiould be used, there's a specific TList written for each need.
It allows you to define your own semantics on the collection (you may not want to have an Add or AddRange method etc...).
Additionally, readability is increased by not having your code littered with List<Touch> and List<Texture> everywhere.
There is also quite a lot of .NET 1.0/1.1 code that still needs to work, so the older collections that predate generics still need to exist.
It's not that easy to use generic classes in XAML for example.
Following on from Oded's answer, your own class type allows for much easier change down the track when you decide you want a stack / queue etc instead of that List. There can be lots of reasons for this, including performance, memory use etc.
In fact, it's usually a good idea to hide that type of implementation detail - users of your class just want to know that it stores Textures, not how.

fields not allowed in C# interface

There are quite a lot of deviations in Java and C# languages, one of which I observed was we cannot add variable constants in an interface. Being from Java background I got baffled to see compilation error when I tried this.
Does anyone has explanation why it is so?
A field is an implementation detail of a class and should not be exposed an its interface.
An interface is a way to abstract away implementation details of a class. These two concepts look contradictory and don't really fit together.
You can declare properties in interfaces instead.
UPDATE (after realizing the question was about constants, not variable fields): I think (purely my personal speculation) that Java decided to allow such a construct because it didn't have enum types back then. C# has had enums since the beginning and preferred those to constants most of the time. Moreover, you can create a static class in C# and add everything you like in it and ship it along the interface without any real hassles. Supporting such a construct would just make interface definitions more complicated.
I've rarely wanted to have an actual constant in an interface - they usually make more sense in classes. The practice of using a Java interface to just contain constants (in order to reduce typing in classes that use them) is nasty; I'd only put constants in interfaces where they were related to functionality within the interface itself.
However, on occasion I've thought it would be nice to be able to define an enum within an interface, if that's the only context in which the enum is anticipated to be used. Interestingly, VB allows this even though C# doesn't.
Effectively both of these would be a way of turning the interface into a "mini-namespace" in its own right. However, I can't say I've missed it very often when writing C#. As the C# team is fond of saying, features aren't removed - they're added, and the cost of adding a feature is very high. That means the feature really needs to pull its weight - there has to be a significant benefit before the feature is added. I personally wouldn't put this very high up on the list.
Related thought: it might be nice to be able to define a nested class within the interface, usually an implementation of the interface - either to express its contracts or to act as a "default" implementation for situations where there is such a thing.
and adding constants to interfaces is discouraged in Java too (according to Effective Java at least)
Adding constants to an interface is wrong and should almost never be done. In the past many people declared Interfaces with many constants and then made another class implement this interface so they could make use of the constants without qualifying said constant. This is of course another anti pattern and was only done because people were lazy. If you really want a constant in an interface define a method that returns that constant.

Converting all parameters, return types, class definitions to use Interfaces

I am in the process of converting all my parameters, return types, classes to all use Interfaces instead ie. IUser instead of User.
Besides the extra code required to maintain this, are their any negatives to this approach?
This isn't an uncommon approach, especially if you do a lot of mocking; however, it has issues with:
data-binding support (especially when adding rows to tables)
xml serialization (including comms WCF, asmx, etc), or contract-based serialization in general
You need to figure out whether the advantages of mocking etc outweigh these issues. It might be that you use IUser in most scenarios, but (for example) at the comms layer it may be simpler to use raw DTOs rather than interfaces.
Note that I'm applying the above to classes. If you involve structs, then remember that in most cases this will involve boxing too.
Overall, this will give you all the advantages associated with loose coupling, so in general I consider this a huge win. However, since you asked about disadvantages, here are some minor ones I can think of:
There's more code involved becase you have both the interface declaration and at least one implementation (you already mentioned this, so I'm just including it for completeness sake).
It becomes more difficult to navigate the code because you can't just Go to Definition to review what another method does (although I'm told that Resharper helps in this regard).
In some cases there may be more in a contract than mere semantics, and an interface can't capture that. The classic example from the BCL is that if you implement IList, you must increment the Count property every time you add an item. However, nothing in the interface forces you, as a developer, to do this. In such cases, abstract base classes may be worth considering instead.
Interfaces are brittle when it comes to adding new members. Once again, you may consider abstract base classes instead.
I once went through a phase of this, but in practice found that for anemic data objects (i.e. POCOs) the interfaces weren't required.
In practice it can be useful to have interfaces to define a contract for behaviour, but not necessarily for attributes.
In general I'd suggest you let your unit testing guide you. If you have rich objects throughout your application then you'll most likely need interfaces. If you have POCOs, you most likely will only need them for controller-style classes.
Interfaces are very good thing, but applying them to all artifacts is overkill. Especially in java you would end up with two distinct files (interface + implementation). So (as always), it really depends :)
Regarding 'interface or not-to-interface'
I would not have domain-objects have interfaces (e.g. User). In my view for code comprehension it is rather confusing (for domain objects interface often would define getter methods). Recently it was a real pain to get unit-tests in place and having domain-object-interfaces. I had to mock all these getters and getting test-data into the domain-object mocks was rather cumbersome.
The opposite is true for coarse grained services and api interfaces. For them I always have an interface from start on.
In more internal-module encapsulated scenarios I start without interface and after some code-evolution if necessary react and do an extract-interface refactoring.
'I' prefix for interface artifact names
I also used to work with the Ixxx prefix but I (happily) got rid of it nowadays for following reasons:
It is difficult to keep up all this 'I' naming convention in an evolving codebase, especially if you refactor a lot (extract-interface, collapse-interface etc.)
For client code it should be transparent whether the type is interface or class based
The 'I' can make you lazy about good interface and classnames.
Not so much a disadvantage but a warning. You would find that to achieve good component de-coupling you will need to use a Dependency Injection framework (that is if you want to keep your sanity and have some sort of idea what your interfaces map to).
What also tends to happen is that non-trivial classes sometimes naturally convert into more than one interface. This is especially true when you have public static methods (i.e. User.CreateAdminUser). You will also find that it's harder to get an interface to hold state AND do stuff. It's frequently more natural for an interface to be either one or the other.
If you get stuck in the process, do take a minute a do some research into what's an appropriate paradigm that you are trying to implement. Chances are someone has solved this particular design pattern before. Considering this is a big refactoring job, you might as well take extra time and do it properly.
avoid the ISuck prefix.
edit: the ISuck convention is a manifestation of the Systems Hungarian notation applied to type names.

Categories

Resources