So I may have coded myself into a corner, and I want to know the best way out.
I have this document editor I'm writing, and one property of the documents being edited is a list of structures. The document is stored as XML, so each of these structures is an XML node and its properties. My Document class exposes these structures as an IEnumerable.
In my editor, I want to literally highlight these structures when the mouse is nearby. I've already done the task of identifying one close to the cursor. But now I have to be able to refer to that instance of the structure, and store that somewhere. Finding the closest one just iterates through the IEnumerable, and returns the structure itself. I suppose that I could use the structure itself as the reference, but then I'm going to wind up saying in my display code if (thing == nearestThing) and it's going to do a hash code comparison or something, right?
That feels like the wrong way to do it, but I don't have a proper ID for these structures either. Suggestions?
There is no problem with that way. Keep in mind though, you should make sure that == (and to a greater extend, Equals and GetHashcode) reliably produce the same results for the same inputs.
Related
I need to serialize a collection that can hold two values object and int.
I have a list of articles that are going to be read by a user and I want to give him the opportunity to come back to the exact sentence where he finished. This method will return three articles and the sentence id.
I used Dictionary to achieve this however I later I found out that serialization of dictionary is not that easy. Then I was thinking array, but I am not sure how to approach this since values should always be different, do you have experience which collection I can use?
I want to have a method that could traverse an object by property names and get me the value of the property.
More specifically as an input I have a string like "Model.Child.Name" and I want this method to take an object and get me the value that could be found programatically via: object.Model.Child.Name.
I understand that the only way to do this is to use Reflection, but I don't want to write this code on my own, because I believe that there are pitfalls. Moreover, I think it is more or less usual task.
Is there any well-known implementation of algorithm like that on C#?
Reflection is the way to go.
Reflection to access properties at runtime
You can take a look at ObjectDumper and modify the source code as per your requirement.
ObjectDumper take a .NET object and dump it to string, file, textWriter etc.
The is not that difficult to write. Yes there are some pitfalls, but it's good to know the pitfalls.
The algorithm is straightforward, it's traversing a tree structure. At each node you inspect it for a primitive value (int, string, char, etc) if it's not one of these times, then its a structure that has one or more primitives and needs to be traversed to it's primitives.
The pitfalls are dealing with nulls, nullable types, value versus reference types, etc. Straight forward stuff that every developer should know about.
Is there some idiomatic, performance or design philosophy reason why C#'s LinkedList's RemoveFirst() and RemoveLast() operations don't return the value removed?
Right now, if I want to read and remove the first value, I believe the incantation is:
LinkedList<string> list = ...;
...
string removed = list.First.Value;
list.RemoveFirst();
In Java, it would be:
LinkedList<String> list = ...;
...
String removed = list.removeFirst();
Don't get me wrong; I am not trying to say Java is better. C#'s LinkedList has many more affordances, simply by exposing the Node as a public construct. I am trying to understand the design choices.
I can't really give a definitive answer, as I can't read the minds of the designers of LinkedList<T>. What I can say is this.
In Java, the LinkedList<E> class implements the Queue<E> interface, which reflects a decision on the designers' part: "You know what? A linked list can easily be used as a queue, so we might as well have it implement that interface." And the way you interact with a queue is by popping items off the end, and then, you know, using them for something (which means it's natural for a Pop-like operation to return the element popped).
In .NET, there is no IQueue<T> interface. Basically, the designers made a different decision: "The most efficient implementation of queue-like behavior we know of is a simple array-based circular queue. So if developers want a queue, they should use the Queue<T> class, which is exactly that."
If a developer wants to use a LinkedList<T> as a queue (or a deque for that matter), chances are he/she is picking the wrong implementation for the data structure he/she actually needs (from the .NET point of view).
Thus, in the spirit of "a proper function should do exactly one thing," the BCL folks opted to make LinkedList<T>.RemoveFirst do just that: remove the first element (similar to how List<T>.RemoveAt just removes the element at the specified index and returns nothing).
I'm not saying either decision is right or wrong. I think the different interfaces of the standard linked list class in Java and .NET simply reflect different views of what a linked list is and how it should be used within the two frameworks.
The programmer may not always want to return the first node when removing it. If RemoveFirst returned the node and the programmer did not need it, it would still require memory allocation and disposal. Optionally storing the first node (using the First property) and having a separate remove function seems more flexible, in my opinion.
Have you considered using a Queue or a Stack collection instead of a LinkedList? you can then push and pop and get the behavior you desire.
The reason that RemoveFirst and RemoveLast doesn't actually return the value is that internally the LinkedList<T> stores nodes as LinkedListNode<T>. The LinkedListNode object has a concept of Next and Previous but if you remove the object from the parent collection where would these properties point?
I have implemented an evolutionary algorithm in C# which kind of works but I have the assumption that the cloning does not. The algorithm maintains a population of object trees. Each object (tree) can be the result of cloning (e.g. after ‘natural selection’) and should be a unique object consisting of unique objects. Is there a simple way to determine whether the ‘object population’ contains unique/distinct objects – in other words whether objects are shared by more than one tree? I hope my question makes sense.
Thanks.
Best wishes,
Christian
PS: I implemented (I think) deep copy cloning via serialization see:
http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx
The way to verify whether two objects are the same objects in memory is by comparing them using Object.ReferenceEquals. This checks whether the "Pointers" are the same.
Cloning in C# is by default a shallow copy. The keyword you probably need to google for tutorials is "deep cloning", in order to create object graphs that don't share references.
What about following: Add a static counter to every class for member references of your 'main tree class'. Increment counter it in every counstructor. Determine how many of a 'subobjects'should be contained in tree object (or all tree-objects) and compare that to the counter.
OK, for first, let me see if I get you correctly:
RESULT is a object tree that has some data.
GENERATION is a collection of a result objects.
You have some 'evolution' method that moves each GENERATION to the next step.
If you want to check if one RESULT is equal to the other, you should implement IComparable on it, and for each of its members, do the same.
ADDITION:
Try to get rid of that kind of cloning, and make the clones manually - it WILL be faster. And speed is crucial to you here, because all heuristic comes down to muscle.
If what you're asking is "how do i check if two object variables refer to the same bit of memory, you can call Object.ReferenceEquals
I have a "manager" class maintaining a list of objects. Each Object has a certain "position", but this is not known to them, only the manager knows about this. The manager must assign each Object a position and maintain its list of Objects sorted according to this "external attribute".
Note that an Object's position can change at any time. Ideally I should be able to immediately get either Element at position X or the position of Element X at any time.
This is C# code. I am wondering what would be a clean or idiomatic way of doing this.
I thought about making an internal class like this:
class SortedElement {
public Element Elem { get; set; }
public int Position { get; set; }
}
And then maintain a list of SortedElements. I don't know, it seems clumsy to me. Two SortedElements could have the same Position for instance. I feel like there's an obvious, clean solution which I'm missing. I could also make the Position a property of the Elements themselves, but it doesn't make sense semantically, meaning there's no reason for them to know about that except making my life easier.
Please make me go facepalm.
EDIT: Following Eric Lippert's advice of listing my requirements, and a good night's sleep, I realized I should opt for a LinkedList<Element> and use the index as position. Indeed, the most common operations here will be insertion at the beginning and removal anywhere within the container, which are expensive on an array-based container.
Thanks for all replies.
Let's list your requirements. I assume you want to have a data structure S which has the following operations:
ContainsElement: takes an element, tells you whether the element is in S
IsValidPosition: takes a Position, tells you whether that position is available in S
GetElementAt: takes a valid Position, returns an Element
GetPositionOf: takes an Element which is in S, returns a Position
InsertElementAt: takes an Element not in S and a valid Position. Puts the element at that position; all elements after that position move "up by one".
RemoveElementAt: takes a valid Position, removes the element at that position, all elements after that position move "down one".
Is that a correct summary of the operations you want? (Note that moving an element to a new position is the same as RemoveElementAt followed by InsertElementAt.)
If those are not a correct summary of the operations, then it would be helpful if you'd list exactly the set of operations you want your abstract data type to support.
Once we have a clear list of requirements for operations then the next question is "what are the asymptotic performance requirements?"
For example, you could use a List<T> as your data structure S; it supports all of those operations. However, if the list is very long then inserting and removing at the beginning of the list is very expensive, as is the "Contains" operation.
There are more exotic data structures you can use that are highly efficient at modeling insertions and removals; we use such data structures to model changes to the state of the editor in the C# IDE. Obviously each token, variable declaration, and so on, is an "element" that has a "position" and that position changes all the time as you type around it; handling those changes in an efficient manner is quite challenging, but if that's the sort of problem space you're in, then describe it more clearly and we can give you pointers on data structures you can do some research on.
You seem to be taking pains to avoid describing the collection as a simple sequence of elements, so I'll assume a List<T> and using the index as position is out of the question. What about a Dictionary<int, Element>? It enforces uniqueness and assuming this "position" you refer to is ordinal, maintains proper sorting.
You could maintain the list of elements internally to the "manager" class using a generic list (List<Element>). You could then sort the list however you wanted using the Sort() method of the List<T> class. For example:
myList.Sort((elem1, elem2) => elem1.Name.CompareTo(elem2.Name));
In this example the elements are sorted by the property "Name", but you could use anything in the comparison, including your "external attribute".
I think you should really use a SortedDictionary.