Any ideas as to why this
public Collection<Point> data = new Collection<Point>(){
new Point{X=10,Y=20},
new Point{X=20,Y=30},
new Point{X=40,Y=20},
new Point{X=10,Y=20}
};
(notice the identical first and last elements)
gives the error
An item with the same key has already been added.
If you change the last element to Y=20.1 or anything that makes it different then it works.
Also you can add the elements anyway you like and get the same result.
The problem is obviously due to Point being a value type because it goes away if you define and use a point class and I know that there are problems with using structs in other collection types but this has to do with the difference between value and ref return types. What mystifies me is that this works if the all the structs have different field values.
The reason is because equality of a value type is based on its values - for struct it is equality across all its fields.
Reference type equality is based on the reference itself and thus works. Changing the struct values to be all different also works.
If you just want a list of stuff, just use List<Point>, I think that will accept duplicates.
Update: it looks like your collection class is detecting duplicate entries and you are trying to add duplicates. If you want to add duplicates, I would say you cannot use this class.
Have you tried using a List instead? I think it should work!
Hope that helps!
I'm not familiar with this collection class you're using but apparently it doesn't allow multiple items to be in it. As it is with a SET collection. So I guess the Collection you're using is equivalent to:
Dictionary<String, Point>
but since you you dont have a key it's more like
HashSet<Point>
Just like your collection class a HashSet requires all keys to be unique. Like Kieren mentions a List would be more suitable for you. A list allows multiple entries to be the same.
Indeed if Point was a class it would allow duplicates since Objec1 != Object2 to even if their values are the same.
I'm really not sure on this, but I have a feeling that because the compiler generates a strong Collections item that doesn't require to box/unbox value types, the key check is done on the explicit value type itself, which produces the duplicate key exception?
That's really just a shot in the dark!
What is Collection class. It's not .NET Framework library class. Look docs or sources of this class, it would explain the problem.
Related
I'm trying to compare 2 objects expectedItems and resultItems of type IEnumerable<IDictionary<string, object>> but haven't been able to do much with it.
Also, one dictionary is initialised in the code, and the other one is built from a JSON response from an external API. Since, JSON doesn't really care about the order of the properties within the object, a SequenceEquals is ruled out.
I do have two equal objects and all of these understated methods are failing,
First,
CollectionAssert.AreEqual(expectedItems, resultItems)
Second,
var expectedItems = entries.Select(e => e.Serialize()).ToList();
resultItems.Zip(expectedItems,(objects, dictionary) =>
objects.OrderBy(pair =>pair.Key).SequenceEqual(dictionary.OrderBy(pair => pair.Key)))
.Should()
.NotContain(false);
The objects (as far as I see) are equal.
Any thing that I can try, or anything that I am currently doing wrong?
EDIT
The API trims the tick count from the timestamp that's why the failure. How can I trim the timestamp in the expectedItems dictionary and then compare? So, the collections have to be same and the comparison for timestamp needs to be overridden. Anyone?
Two things to check:
Are the object implementing preperly the Equals() method? If not the equality just check for the reference, and since they are two different instance they appear to be different.
Another option could be, since your object is representing a Timestamp, as I guess by the picture.
even if it properly implements Equals, are the objects the same even in term of the millisecond ( if existing ) portion?
Why don't you install FluentAssertions and do something like this?
resultsItem.ShouldAllBeEquivalentTo(expectedItems);
I don't know by heart how restrictive the DateTime comparison is, but you can easily override the behavior for a particular property.
I have 2 classes. One handles a ReferenceType value, another does the same on a ValueType value. This is the only difference, but it is important. I am struggling to find a decent name for each class:
ReferenceTypeValueHandler and ValueTypeValueHandler?
Neah, ValueTypeValue sounds confusing.
ClassValueHandler and StructValueHandler?
I shouldn't use "Class" in a name of a class, should I?
NullableValueHandler and NonNullableValueHandler?
"Nullable" is already used for nullable value types (Nullable<>)
HeapValueHandler and StackValueHandler?
That's dumb. Exploiting the fact that reference type values are stored in the heap and value type values are in the stack, who cares? Also "Stack" is confusing implying it has something to do with a stack.
Any more ideas?
Update:
Some people suggest I should explain the purpose of the class. Well, although I don't think it's important, here it is: I am working on a XML to entity deserializer. I use XmlReader to take advantage of the streamline reading rather then working with DOM. As I read XML I build entities. Some entities are just wrappers for some other ones. These wrappers can take either a single entity or a collection (enumerable) of entities. Speaking of those which take a single entity, this entity has to be provided and it has to be provided exactly one time. If XML doesn't have it, it's a problem. If XML has more than 1 it's a problem too. So for keeping and ensuring that the entity is provided exactly one time I have a class ValueKeeper<TValue>. It has 2 methods TakeValue(TValue value) and TValue ClaimValue(). The TakeValue methods takes the value and checks if there is already a value provided before, if so it throws the exception with appropriate details. The ClaimValue method is called once the reading of the wrapper XML is finished and the wrapper entity has to be created over the scraped value, this method checks whether there is a value that was received via the TakeValue method, if so
it just returns that value, if no, then it throws the exception. Now, the problem is that for reference type values I am using comparison to NULL in order to see if the value was provided. In order to make such comparison possible there must be a generic constraint on the TValue type parameter: where TValue: class. Having this constraint in place I cannot use this class for value type values. So I need another class that does the same, but operates on values where TValue: struct using a Nullable<TValue> field to keep either provided or not-yet provided value. Now, with 2 classes I cannot go along just with ValueKeeper, I need one name for the reference type and another for the value type value. Here is where the question comes up. I need a way to express this subtle difference. But again, it's not important what the class does, what's important is to find appropriate way to put this difference clear.
I wouldn't agree that the rest of the class name is not important. You want to make your code speak for itself and to make it easy for the reader to understand the concepts you had in mind when designing the classes/structs. The class names you suggest would give me no idea of what the class is actually doing. I suggest to search for more concrete names: How is the value being handled? What value?
How do struct and class values differ from each other apart from that one is a class and the other one a struct? There must be some more difference because otherwise it wouldn't make sense to have the same thing as a struct and as a class (DRY).
If it's a very abstract operation you perform, try to search for the pattern, or a general name for a concept. To keep the value and make sure it was provided sounds a bit like a caching mechanism?
Secondly, your facing a semantic issue here: what is the term which subsumes 'values' of value types and 'values' of reference types. We could simply ask the inheritance chain of the .NET framework here and call it both an object.
So, in this case, something like CacheForValueTypeObjects and CacheForReferenceTypeObjects could work. I don't know whether cache expresses the purpose well, but if not, I would try to search for a term which best describes the 'final' purpose of the class, the reason why its there.
I bet you didn't think 'Well, what I really need now is a ValueTypeValueHandler!'. There was something more to it. ;) I like this kind of questions, thanks!
I have a dictionary data structure that must be passed around using WCF. To do that I created a member property with get and set methods. I can basicly achieve the same functionality, with this property being either a:
IDictionary<keyType, valueType>
or a
IList<KeyValuePair<keyType, valueType>>
I can see no strong reason for choosing one over the other. One mild reaons I could think of is:
IDictionary - People reading the code will think that IDictionary makes more sense, since the data structure is a dictionary, but in terms of what is passed through WCF they are all the same.
Can anyone think of a reason to choose IList? If there is none I'll just go with IDictionary.
Design your interfaces based on use, not on implementation.
If the consumer of a class needs to iterate through the entire set, use IEnumerable. If they should be able to modify the result, and need index-based access, return IList. If they want specific items, and there is a single useful key value, return IDictionary.
Write your internal code this way, too :)
It depends on your consumers. I would cater for the most likely use case and make their API as simple as possible. Edge cases can always iterate the dictionary via the Values collection.
Don't make them think about it. If the the term dictionary is what they'd think about as the result of the operation and then the type with name is a very useful thing to use.
If the collection of keyValuePairs expects unique key, you can use dictionary.
If the same key can appear in more than one keyValuePair, use Ilist/ ienumerable.
To make it easy, lets say I have an arraylist allBooks containing class "books" and an arraylist someBooks containing some but not all of the "books".
Using contains() method worked fine when I wanted to see if a book from one arraylist was also contained in another.
The problem was that this isn't working anymore when I save both of the Arraylists to a .bin file and load them back once the program restarts. Doing the same test as before, the contains() returns false even if the compared objects are the same (have the same info inside).
I solved it by overloading the equals method and it works fine, but I want to know why did this happen?
You will have to provide your own hash code and equals implementation. By default, it will simply use pointer equality, which obviously fails after objects been 'cloned' (serialized/ deserialized cycle).
What happened was that when you originally created the lists they both contained references to the same objects, but when you loaded them back in they both got separate copies of the same objects. Since each list got separate copies, they didn't contain the same references, meaning they didn't compare as equal without overloading the right method.
This sounds like the common issue of referential equality vs Equals, and is especially common with serialization. Override Equals (and GetHashCode) appropriately and you should be back in business.
For info, using ArrayList should generally be avoided unless you are using .NET 1.1 (or micro-framework), or have a very valid reason to do so; prefer the generic typed collections, such as List<T>.
Assuming book is an object, by default Equals checks if the reference is equal. That cannot be the case when you load new objects. Overwriting the Equals method is a right approach.
Other options are to change Book to a struct, or using a more modern container, like a dictionary or hashtable, where you can store books by id.
I've been using a Hashtable, but by nature, hashtables are not ordered, and I need to keep everything in order as I add them (because I want to pull them out in the same order). Forexample if I do:
pages["date"] = new FreeDateControl("Date:", false, true, false);
pages["plaintiff"] = new FreeTextboxControl("Primary Plaintiff:", true, true, false);
pages["loaned"] = new FreeTextboxControl("Amount Loaned:", true, true, false);
pages["witness"] = new FreeTextboxControl("EKFG Witness:", true, true, false);
And when I do a foreach I want to be able to get it in the order of:
pages["date"]
pages["plaintiff"]
pages["loaned"]
pages["witness"]
How can I do this?
I believe that .NET has the OrderedDictionary class to deal with this. It is not generic, but it can serve as a decent Hashtable substitute - if you don't care about strict type safety.
I've written a generic wrapper around this class, which I would be willing to share.
http://msdn.microsoft.com/en-us/library/system.collections.specialized.ordereddictionary.aspx
EDIT: LBushkin is right - OrderedDictionary looks like it does the trick, albeit in a non-generic way. It's funny how many specialized collections there are which don't have generic equivalents :( (It would make sense for Malfist to change the accepted answer to LBushkin's.)
(I thought that...) .NET doesn't have anything built-in to do this.
Basically you'll need to keep a List<string> as well as a Dictionary<string,FreeTextboxControl>. When you add to the dictionary, add the key to the list. Then you can iterate through the list and find the keys in insertion order. You'll need to be careful when you remove or replace items though.
use sorted list i think it will solve your problem
becuase SortedList object internally maintains two arrays to store the elements of the list; that is, one array for the keys and another array for the associated values. Each element is a key/value pair that can be accessed as a DictionaryEntry object
SortedList sl = new SortedList();
foreach(DictionaryEntry x in sl)
{}
Use the KeyedCollection
Its underlying base is a List but provides a dictionary lookup based on key. In this case your key is the strings. So as long as you aren't adding the same key twice you are fine.
http://msdn.microsoft.com/en-us/library/ms132438.aspx
There's no perfect solution before .NET 4.0. In < 3.5 You can:
Use a generic SortedList with integer key-type, and value type of the most-derived common type of your items. Define an integer value (i, let's say) and as you add each item to the SortedList, make the key i++, incrementing it's value as you go. Later, iterate over the GetValueList property of the sorted list. This IList property will yield your objects in the order you put them in, because they will be sorted by the key you used.
This is not lightening-fast, but pretty good, and generic. If you want to also access by key, you need to do something else, but I don't see that in your requirements. If you don't new to retrieve by key, and you add items in key order so the collection doesn't actually have to do its sorting, this is it.
In .NET 4.0 you'll have the generic SortedSet Of T, which will be absolutely perfect for you. No tradeoffs.
The best way is to use the C# indexers. It is configurable to anything we like. We can pass an int, enum, long, double or anything we like.
Just have to create a class and give it indexers and configure input and output parameters. It is a little more work but I think this is the only right way.
Please see this MSDN link for more information how to use it.
See Indexers: http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx
One alternative is to keep your ordered key values in an ordered structure like a List, the rest being still stored in a dictionnary.
Then, when you need to access your data, just go through your sorted List and query your dictionnary along the way.
look at sorted list
http://msdn.microsoft.com/en-us/library/system.collections.sortedlist.aspx
As Haxelit suggests, you might derive from KeyedCollection<TKey, TValue>. It actually uses a List underneath until you hit a certain threshold value, and then it maintains both a List and a Dictionary. If you can use a function to derive one of your keys from one of your values, then this is an easy solution. If not, then it gets pretty messy.