I was reading XNA library code and inside the type VertexPositionColor, they supress the CA2105:ArrayFieldsShouldNotBeReadOnly message with the justification "The performance cost of cloning the array each time it is used is too great."
public struct VertexPositionColor
{
public static readonly VertexElement [ ] VertexElements;
}
But why would it be copied when it's used? This only happens for structs where the accessed property/field is a ValueType, right?
I guess they are justifying the fact that they are exposing an array field more than anything else and the underlying reason of why they are doing so is performance:
The alternative they probably had in mind was making the array field private with a property exposing an IEnumerable or returning a copy of the array each time the property was accesed.
EDIT. Edited the answer a little to make clearer what I was trying to say :p.
In most cases they'd be better off using Array.AsReadOnly and returning a generic ReadOnlyCollection. According to the documentation that's an O(1) operation.
In the current implementation callers can change the values in the array (modifying the static/global state directly).
One more reason to read Framework Design Guidelines - it gives you the reasons behind FxCop's recommendations.
Related
Coming from a C++ background and trying to learn C#, one of the most frustrating language omissions that I've come across is an equivalent to the const keyword.
So, I have been attempting to settle on a pattern that I can use to achieve const correctness in C#.
This answer has an interesting suggestion: create a read only interface for all of your types. But as Matt Cruikshank pointed out in the comments, this becomes problematic if your class has collections or other rich types. Particularly if you do not have control over the type, and can't make it implement a read-only interface.
Do any patterns or solutions exist that can handle rich types and collections, or are we forced in C# to simply make copies? Is it better to just give up on const correctness in C# altogether?
Can you get immutability in C#? Sure, if you design for it. You can do creative things with interfaces, and so on, to only expose the get of properties and none of the mutable methods.
That said, keep in mind there is nothing that prevents a crafty user from casting it back to the actual type (of course, same could be said of C++, you can cast away const-ness).
ISomeReadOnlyInterface readOnly = new SomeFullObject();
// hah, take that read-only interface!
((SomeFullObject)readOnly).SomeMutatingMethod();
Same with collections. Even if you return a ReadOnlyCollection (which prevents mutating behaviors on the collection itself) the data in the collection is still mutable (as long as the type allows it of course).
So I'm afraid there's really no simple answer here. There's no "flip-a-switch" const that gives you what C++ does.
It's really up to you, you can:
Design your types to be immutable and return iterators (or other read only sequences) instead of mutable collections.
Return new copies each time so that if they alter them it's no biggie.
Just return the actual data and leave tampering behavior as "undefined".
etc...
The latter is what collections like Dictionary<TKey, TValue> do. There's nothing that says you can't make the key type a mutable type (but woe if you do), and the MSDN is pretty clear that if you alter the key in such a way that it's hash code changes, it's on your own neck...
For my own work, I tend to keep it simple unless there is actually a big concern my class may be altered in a way that would cause side-effects. For example, if I'm storing web service results in a cache, I'll return a copy of the cached item instead so that if a user modifies the result they won't inadvertently modify the cached value.
So, long and the short of it is that I wouldn't worry about const-correctness of every type you return, that's just way too much. I'd only worry about things that you return that, if altered, could create a side-effect to other users.
From this Answer, I came to know that KeyValuePair are immutables.
I browsed through the docs, but could not find any information regarding immutable behavior.
I was wondering how to determine if a type is immutable or not?
I don't think there's a standard way to do this, since there is no official concept of immutability in C#. The only way I can think of is looking at certain things, indicating a higher probability:
1) All properties of the type have a private set
2) All fields are const/readonly or private
3) There are no methods with obvious/known side effects
4) Also, being a struct generally is a good indication (if it is BCL type or by someone with guidelines for this)
Something like an ImmutabeAttribute would be nice. There are some thoughts here (somewhere down in the comments), but I haven't seen one in "real life" yet.
The first indication would be that the documentation for the property in the overview says "Gets the key in the key/value pair."
The second more definite indication would be in the description of the property itself:
"This property is read/only."
I don't think you can find "proof" of immutability by just looking at the docs, but there are several strong indicators:
It's a struct (why does this matter?)
It has no settable public properties (both are read-only)
It has no obvious mutator methods
For definitive proof I recommend downloading the BCL's reference source from Microsoft or using an IL decompiler to show you how a type would look like in code.
A KeyValuePair<T1,T2> is a struct which, absent Reflection, can only be mutated outside its constructor by copying the contents of another KeyValuePair<T1,T2> which holds the desired values. Note that the statement:
MyKeyValuePair = new KeyValuePair(1,2);
like all similar constructor invocations on structures, actually works by creating a new temporary instance of KeyValuePair<int,int> (happens before the constructor itself executes), setting the field values of that instance (done by the constructor), copying all public and private fields of that new temporary instance to MyKeyValuePair, and then discarding the temporary instance.
Consider the following code:
static KeyValuePair MyKeyValuePair; // Field in some class
// Thread1
MyKeyValuePair = new KeyValuePair(1,1);
// ***
MyKeyValuePair = new KeyValuePair(2,2);
// Thread2
st = MyKeyValuePair.ToString();
Because MyKeyValuePair is precisely four bytes in length, the second statement in Thread1 will update both fields simultaneously. Despite that, if the second statement in Thread1 executes between Thread2's evaluation of MyKeyValuePair.Key.ToString() and MyKeyValuePair.Value.ToString(), the second ToString() will act upon the new mutated value of the structure, even though the first already-completed ToString()operated upon the value before the mutation.
All non-trivial structs, regardless of how they are declared, have the same immutability rules for their fields: code which can change a struct can change its fields; code which cannot change a struct cannot change its fields. Some structs may force one to go through hoops to change one of their fields, but designing struct types to be "immutable" is neither necessary nor sufficient to ensure the immutability of instances. There are a few reasonable uses of "immutable" struct types, but such use cases if anything require more care than is necessary for structs with exposed public fields.
Ok, as I understand it, immutable types are inherently thread safe or so I've read in various places and I think I understand why it is so. If the inner state of an instance can not be modified once the object is created there seems to be no problems with concurrent access to the instance itself.
Therefore, I could create the following List:
class ImmutableList<T>: IEnumerable<T>
{
readonly List<T> innerList;
public ImmutableList(IEnumerable<T> collection)
{
this.innerList = new List<T>(collection);
}
public ImmutableList()
{
this.innerList = new List<T>();
}
public ImmutableList<T> Add(T item)
{
var list = new ImmutableList<T>(this.innerList);
list.innerList.Add(item);
return list;
}
public ImmutableList<T> Remove(T item)
{
var list = new ImmutableList<T>(this.innerList);
list.innerList.Remove(item);
return list;
} //and so on with relevant List methods...
public T this[int index]
{
get
{
return this.innerList[index];
}
}
public IEnumerator<T> GetEnumerator()
{
return innerList.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ((System.Collections.IEnumerable)this.innerList).GetEnumerator();
}
}
So the question is: Is this really an immutable type? Is it really thread safe?
Obviously the type itself is immutable but there is absolutely no garantee that T is and therefore you could have concurrent access and threading issues related directly with the generic type. Would that mean that ImmutableList should be considered mutable?.
Should class ImmutableList<T>: IEnumerable<T> where T: struct be the only type truly considered immutable?
Thanks for any input on this issue.
UPDATE: A lot of answers/comments are concentrating on the particular implementation of ImmutableList I've posted which is probably not a very good example. But the issue of the question is not the implementation. The question I'm asking is if ImmutableList<MutableT> is really an immutable type considering everything that an immutable type entails.
If the inner state of an instance can not be modified once the object is created there seems to be no problems with concurrent access to the instance itself.
That is generally the case, yes.
Is this really an immutable type?
To briefly sum up: you have a copy-on-write wrapper around a mutable list. Adding a new member to an immutable list does not mutate the list; instead it makes a copy of the underlying mutable list, adds to the copy, and returns a wrapper around the copy.
Provided that the underlying list object you are wrapping does not mutate its internal state when it is read from, you have met your original definition of "immutable", so, yes.
I note that this is not a very efficient way to implement an immutable list. You'd likely do better with an immutable balanced binary tree, for example. Your sketch is O(n) in both time and memory every time you make a new list; you can improve that to O(log n) without too much difficulty.
Is it really thread safe?
Provided that the underlying mutable list is threadsafe for multiple readers, yes.
This might be of interest to you:
http://blogs.msdn.com/b/ericlippert/archive/2011/05/23/read-only-and-threadsafe-are-different.aspx
Obviously the type itself is immutable but there is absolutely no garantee that T is and therefore you could have concurrent access and threading issues related directly with the generic type. Would that mean that ImmutableList<T> should be considered mutable?.
That's a philosophical question, not a technical one. If you have an immutable list of people's names, and the list never changes, but one of the people dies, was the list of names "mutable"? I would think not.
A list is immutable if any question about the list always has the same answer. In our list of people's names, "how many names are on the list?" is a question about the list. "How many of those people are alive?" is not a question about the list, it is a question about the people referred to by the list. The answer to that question changes over time; the answer to the first question does not.
Should class ImmutableList<T>: IEnumerable<T> where T: struct be the only type truely considered immutable?
I'm not following you. How does restricting T to be a struct change anything? OK, T is restricted to struct. I make an immutable struct:
struct S
{
public int[] MutableArray { get; private set; }
...
}
And now I make an ImmutableList<S>. What stops me from modifying the mutable array stored in instances of S? Just because the list is immutable and the struct is immutable doesn't make the array immutable.
Immutability is sometimes defined in different ways. So is thread-safety.
In creating a immutable list whose purpose is to be immutable, you should document just what guarantees you are making. E.g. in this case you guarantee that the list itself is immutable and does not have any hidden mutability (some apparently immutable objects are actually mutable behind the scenes, with e.g. memoisation or internal re-sorting as an optimisation) which removes the thread-safety that comes from immutability (though one can also have such internal mutations performed in a manner that guarantees thread-safety in a different way). You are not guaranteeing that the objects stored can be used in a thread-safe manner.
The thread-safety that you should document relates to this. You can not guarantee that another object won't have the same object (you could if you were creating new objects on each call). You can guarantee that operations will not corrupt the list itself.
Insisting upon T : struct could help, as it would mean that you could ensure that each time you return an item, it's a new copy of the struct (T : struct alone wouldn't do that, as you could have operations that didn't mutate the list, but did mutate its members, so obviously you have to also do this).
This though limits you in both not supporting immutable reference types (e.g. string which tends to be a member of collections in lots of real-world cases) and doesn't allow a user to make use of it and provide their own means of ensuring that the mutability of the contained items doesn't cause problems. Since no thread-safe object can guarantee that all the code it is used in is thread-safe, there's little point tryint to ensure that (help as much as you can by all means, but don't try to ensure what you can't ensure).
It also doesn't protect mutable members of immutable structs in your immutable list!
Using your code, let's say i do this:
ImmutableList<int> mylist = new ImmutableList<int>();
mylist.Add(1);
... your code, posted on StackOverflow, causes a StackOverflow-Exception. There are quite a few sensible ways to create thread save collection, copying collections (at least trying to) and calling them immutable, a lot, doesn't quite do the trick.
Eric Lippert posted a link that might be very worth reading.
A prime example of a data type that behaves as an immutable list of mutable objects: MulticastDelegate. A MulticastDelegate may be modeled pretty accurately as an immutable list of (object, method) pairs. The set of methods, and the identities of the objects upon which they act are immutable, but in the vast majority of cases the objects themselves will be mutable. Indeed, in many if not most cases, the very purpose of the delegate will be to mutate the objects to which it holds references.
It is not the responsibility of a delegate to know whether the methods it's going to invoke upon its target objects might mutate them in thread-unsafe fashion. The delegate is responsible merely for ensuring that its lists of functions and object identities are immutable, and I don't think anyone would expect it to likewise.
An ImmutableList<T> should likewise always hold the same set of instances of type T. The properties of those instances might change, but not their identity. If a List<Car> was created holding two Fords, serial #1234 and #4422, both of which happened to be red, and one of the Fords was painted blue, what started out as a list of two red cars would have changed to a list holding a blue car and a red car, but it would still hold #1234 and #4422.
I would say that generic list is not immutable if the element is mutable, because it does not represent the full snapshot of the data state.
To achieve immutability in your example you would have to create deep copies of list elements, which is not efficient to do every time.
You can see my solution to this problem at IOG library
I believe that one thing adding to the rather lengthy discussion on this topic is that immutability/mutability should be considered along with scope.
As an example:
Say that I am working with a C# project and I define a static class with static data structures, and I define no way to modify those structures in my project. It is in effect a read-only cache of data that I can use, and for the purposes of my program, it is immutable from one run of my program to the next. I have total control over the data, and I/the user am/is unable to modify it at run time.
Now I modify my data in my source code and re-run the program. The data has changed, so in the highest sense of the word, the data is no longer immutable. From the highest level perspective, the data is actually mutable.
I would therefore posit that what we need to be discussing is not the black and white question blanketing something as immutable or not, but rather we should consider the degree of mutability of a particular implementation (as there are few things that actually never change, and are therefore truly immutable).
I have read a lot about the danger of using structures as a data type, I wonder if there is any problem with this one,
List<Summarized> SummarizedList = new List<Summarized>();
Summarized SumInfo;
struct Summarized
{
public string sBrand;
public string sModel;
public string sCustomer;
public int sline;
public string sLeader;
public int sDesire;
public int sReal;
}
As you can see I use a generic list of items type SumInfo which is the struct data type. whenever I need to update an item of the list I just do the following:
SumInfo = (Summarized)SummarizedList[CurrentPos];
SumInfo.sDesire = DesireProd;
SumInfo.sReal = RealProduced;
SummarizedList[CurrentPos] = SumInfo;
where CurrentPos is the position of the item I want to update.
Everything works fine so far, so could be any problem with that in the future? Is this struct one of the mutable ones?
Thanks.
Everything works fine so far, so could be any problem with that in the future? Is this struct one of the mutable ones?
Yes, it's a mutable struct. Yes, it will work.
However, I would argue that this struct should be a class. For details as to why, refer to Choosing Between Classes and Structures. In this case, you're violating 3 of the cases which should always be true for structs:
It logically represents a single value, similar to primitive types (integer, double, and so on).
It has an instance size smaller than 16 bytes.
It is immutable.
This would strongly suggest a class is more appropriate for your type. It would also simplify your code.
BTW - Side note, the cast is not required in your code above. You should be able to just write:
SumInfo = SummarizedList[CurrentPos];
Issues:
It's a mutable struct, and they're almost always a bad idea (search for "mutable structs evil" and you'll get loads of hits)
It's got public fields - therefore no encapsulation; no separation between the API of the type an its implementation
It's got public members which don't follow the normal .NET naming conventions
It doesn't logically represent a single value, as per the .NET design guidelines
It's larger than the 16 bytes recommended by the same guidelines (although I wouldn't pay too much attention to that if everything else were okay)
Basically it's a dumb data bucket. There's a time and place for that, but it should almost always be a class in that case, and I'd personally usually try to make it an immutable type as well.
is there any reason you're using a struct? if you made it a class, the List would just contain references, and your code would look like:
SumInfo = SummarizedList[CurrentPos];
SumInfo.sDesire = DesireProd;
SumInfo.sReal = RealProduced;
// you're done! no need to insert it back in, you're referring to the same item
Personally, I would have nothing against using this struct. It may depend more on how you use it, whether you encapsulate the List methods etc.
The mutability of it depends on whether you are expecting to update any antries once you have added them to the list. If you are not expecting to, then your STRUCT is immutable, but your list isn't. However in this case you are updating the entries, so it is.
I would concur that a class is probably a better option for this.
Issue 1:
Yes the struct is mutable. And it suffers from all the problems associated with that.
SummarizedList[CurrentPos].sDesire=DesireProd;
shows why using a mutable struct like this is a bad idea, since it will not change the struct in the list.
Issue 2:
You have public mutable fields. This is considered bad style and you should use properties instead.
Issue 3:
You're using (System) Hungarian notation. When developing in C# follow the .net naming conventions.
In a recent project I was working I created a structure in my class to solve a problem I was having, as a colleague was looking over my shoulder he looked derisively at the structure and said "move it into a class".
I didn't have any argument for not moving it into a class other than I only need it in this class but this kind of falls down because couldn't I make it a nested class?
When is it ok to use a structure?
You should check out the value type usage guidelines: http://msdn.microsoft.com/en-us/library/y23b5415(vs.71).aspx
The article lists several important points but the few that I feel are the most valuable are the following
Is the value immutable?
Do you want the type to have value semantics?
If the answer to both questions is yes then you almost certainly want to use a Structure. Otherwise I would advise going with a class.
There are issues with using structures with a large amount of members. But I find that if I consider the two points above, rarely do I have more than the recommended number of members / size in my value types.
MSDN has a good guidelines document to cover structure usage. To summarize:
Act like primitive types.
Have an instance size under 16 bytes.
Are immutable.
Value semantics are desirable.
Otherwise, use a class.
You should always use a Class as your first choice, changing to Structure only for very specific reasons (as others have already outlined).
Depending on how much you "only need it in this class", you might be able to avoid the nested type completely by using an anonymous type; this will only work within a single method:
Public Class Foo
Public Sub Bar
Dim baz = New With { .Str = "String", .I = 314 }
End Sub
End Class
you can't (readily--there are a few things you can do with generics) move the instance baz outside of the Sub in a typesafe manner. Of course an Object can hold anything, even an instance of an anonymous type.
I think structures are great if you need copy the object or do not want it to be modified by the passed function. Since passed functions can not modify the originally passed structure instead got a new copy of it, this can be a life saver. (unless they passed as ByRef obviously) and can save you trouble of deep copy craziness in .NET or implementing pain of an ICloneSomething implementation.
But the general idea is defining a custom data structure in a more semantic way.
About moving to a class, if you are moving into a class where it'll be part of a class, generally this is good practice since your structure is 99% of the time related with one of you classes not related with a namespace.
If you are converting it to a class then you need to consider "is it defining a data strcuture" and "is it expensive?" since it's gonna be copied all over the place, "do you want to get affected by modifications done by the passers?"
The usage guidelines referenced by Marc and Rex are excellent and nicely cover cases where you aren't sure which one you would want. I will list some use cases where use of a struct is a requirement.
When you need to set the layout of the fields in memory
Interop with unmanaged code.
When you want to make Unions.
You need a fixed size buffer inlined.
You want to be able to do the equivalent of a reinterpret_cast with relative safety (so long as the struct does not contain any fields which are themselves reference types.
These are normally edge cases and (with the exception of interop) not recommended practices unless their use is necessary for the success of the project/program.