Dictionary uses object as key. The key is updated outside the dictionary - c#

Consider a simple class:
public class TestClass<Val>
{
public Val Value{get;set;}
}
Create an instance of this class and define a dictionary where we use it as a key.
TestClass<int> TestCase = new TestClass<int>();
Dictionary<TestClass<int>, int> D = new Dictionary<TestClass<int>, int>();
Put 0 into the TestCase and add the entry to dictionary:
TestCase.Value=0
D.Add(TestCase,10)
Now the dictionary looks like this: {TestCase -> Value=0:10}
Now do this:
TestCase.Value=1
Now I have in the dictionary {TestCase -> Value=1 : 10} automatically, without putting the key 'TestCase -> Value=1' into the dictionary. How can I avoid it?

Basically, don't use mutable types as keys... or if you do, make sure you never mutate the key. The first would be preferable.
An even bigger problem is that if TestClass<Val> has a custom GetHashCode() / Equals() implementation, you can completely break the dictionary, as it may no longer be able to find a value for that key, even if you give it the exact instance you started with.
Anything you use as a key should ideally be immutable. For that reason, int and string make great choices, but you can also just make your type immutable, as per #lazyberezovsky's example.

Create immutable TestCase class:
public class TestClass<Val>
{
public TestClass(Val value)
{
Value = value;
}
public Val Value{ get; private set; }
}

Actually there is one single instance of TestClass. You created it outside dictionary and then added that instance to dictionary.
If you make changes to instance it reflects inside dictionary. This is shallow copying
To avoid this problem create a deepclone of your instance and then add in dictionary. In that case changes in one will not be reflected in another.

Related

c# object by name in static method

My question is: Can I define a static method "meth1" in a static class "classB" that, when called from "classA", searches for a specific field (in "classA", not in the class in which is defined)?
I try to explain better: I need to do something like this:
public class classA
{
string someText;
int anInt;
bool trueOrFalse;
public classA()
{
...
...
var variable = classB.meth1("variableName");
...
...
}
}
public static classB
{
public static object meth1(string name)
{
...
... //use "name" to find the variable with that name in the class from which "meth1" is called.
...
}
}
That because I have to read a backup of "last run values" of variables contained in a .txt file, written line by line as "variable name = value".
So I read the .txt, create an hashtable "backupHashtable" which contains ("variable name";"value"), and then I want to search variables by string "variable name" and reset them to "value".
If someone of you knows a better procedure I'm listening. Maybe the use of a Dictionary?
Thank you!
UPDATING
Ok, now I have a clearer idea of what I want to do: I want to implement a class "ClassB", separate from my main class "classA". In this new class I would have a "meth1" method which, running in a separate thread, saves every 10 seconds (for example) the state of some variables belonging to "classA". To communicate the "meth1" what are the variables that he has to save, I want to use a list containing the names (in the format "string", that's what I thought, but I guess it's not the only way) of these variables.
If you're wondering why I want to do this in a separate thread the answer is this: my application performs some recognition operation of some objects in live stream images from multiple cameras and then ancillary operations must be isolated as much as possible from the main code to increase the speed of execution.
Now, perhaps, it is more understandable what I said before.
Yes, but you also need to pass a reference to the instance of A. Then use reflection to get or set the property.
public static void Meth1(object obj, string propertyName)
{
var prop = obj.GetType().GetProperty(propertyName);
var value = prop.GetValue(obj);
...
}
If I were to get values from a textfile into a class, I think I'd load them in a dictionary first, and then set all properties one by one. (Maybe unless there are, say, hundreds of properties). When using reflection, there is a chance that the textfile contains the name of a property you don't want to be changed from outside.
object value;
if (dict.TryGetValue("someProperty", out value)) { a.SomeProperty = value; }

Is value in the dictionary becomes a pointer?

If I put an object in the dictionary, whether it becomes a pointer?
I have the following dictionary:
public Dictionary<string, Class1> Dic{ get; set; }
In the following function I update / add to the dictionary
private void Update(string Name)
{
if (Name== null || Name=="")
return;
if (Dic.ContainsKey(Name))
{
Dic[Name] = MyClass;
}
else
{
Dic.Add(Name, MyClass);
}
}
MyClass is a variable that sitting in the same class with the dictionary
public Class1 MyClass { get; set; }
When i changed the class i call to update function, i see that all the dictionary contaion the same value: current MyClass , why?
How can I prevent this?
You are adding the same class object against multiple keys in your dictionary, but all of them are pointing to the same object that is why when you change one object, you see the changes across the dictionary. You need to make copy of your class object and then add it to the dictionary.
You may see this discussion: How do you do a deep copy an object in .Net (C# specifically)? on Stackoverflow.
Other than that, you can get rid of your check against keys, since you are checking if the key doesn't exist add, otherwise update. you can simply do:
private void Update(string Name)
{
if (Name== null || Name=="")
return;
Dic[Name] = MyClass;
}
Which would do the same (add if doesn't exist and update if exist)
Because the class you put in is by reference, so when you change it someplace, it 'changes' there, too (it doesn't really change there, it only changes in one place, but we're all looking at the same thing, so to speak). So, it's nothing really to do with the dictionary, but the mechanics of .NET.
You wouldn't see such changes reflected if you put a value type in, say an integer, then changed the variable value. You could define structures, if appropriate for your situation, which are value types, and you could 'reuse' the type without 'cascading changes'.
No. And sort-of-yes. You never "put and object in the dictionary" - you actually put a reference to an object into the dictionary. The reference points to the original object : the object is not cloned.
If Class1 was a struct, then it would indeed be copied whenever you access it or insert it.
In human terms: a reference is the written address to a house, say. Lots of people can have a copy of that address. If somebody goes to the house and paints the door red, then that is seen by everyone who looks at that address.
(I think I stole this analogy from Jon; sorry Jon)
It sounds like you are doing something like:
MyClass obj = new MyClass();
foreach(var name in names) {
obj.Update(name);
}
when you should be doing:
foreach(var name in names) {
MyClass obj = new MyClass();
obj.Update(name);
}
The distinction here is how many objects we have.
Because class is a reference type. That means every variable of that type is a pointer to that type.
Your class is a reference type, so Dictionary contains it's memory link. Actually you can check more at reference types and value types

Can pointers be used with Dictionary<TKey,TSource>?

Let's say I have the following class:
public class MyClass {
public string FirstAttribute {
get {
return Attributes["FirstAttribute"];
}
set {
Attributes["FirstAttribute"] = value;
}
}
public string SecondAttribute {
get {
return Attributes["SecondAttribute"];
}
set {
Attributes["SecondAttribute"] = value;
}
}
public Dictionary<string, string> Attributes;
public MyClass(Dictionary<string,string> att) {
Attributes = att;
}
}
and I wanted to be able to obtain a pointer to the value that is stored in the Dictionary, so that I can get and set the values (yes unsafe) directly without having to wait for the Dictionary to search for the element by key every time.
Is there a way to do that in c#?
No, I don't believe so. You could store a mutable wrapper in the dictionary though:
public class Wrapper<T>
{
public T Value { get; set; }
}
Then create the dictionary (which should be private, by the way - public fields are a really bad idea other than for constants) as a Dictionary<string, Wrapper<string>>. You can then keep fields for the Wrapper<string> objects associated with "FirstAttribute" and "SecondAttribute".
Frankly I don't think this would be a particularly good idea - I'd just stick with the dictionary lookup - but it's an option. (Assuming nothing's going to change which wrapper is associated with the keys.)
Another option is simply to use fields for the two specific attributes - when you're asked to set a new value, set it in the dictionary and set a field. When you're asked for the current value, just return the value from the field. Of course, that's assuming that you're in control of the dictionary (i.e. so it can't change outside your class).
No, no, no, no.
strings are immutable for a reason. A string might be shared between multiple references: modifying it directly with unsafe code might lead to weird behavior.
A way to go around this would be to write a wrapper class that olds your value, and keep a reference to an instance of that wrapper. The getters and setters would then modify the wrapper's property.
If the values in the dictionary were mutable, you could grab the reference to them and mutate them. But strings are immutable. So the dictionary has its own copy of a reference to your string, and you can't alter the string it is pointing to. If you try to replace it with another string, you need to update the dictionary with the new reference. So basically there's no way to improve on what you have in this situation.

A dictionary with a built-in factory?

I have a solution that works, but for educational purposes I want to understand if there is a better/cleaner/right way to do it.
Problem: In my "client" app I have a dictionary Dictionary<String, PremiseObject> where the key (String) is a immutable URL to a resource (it's actually a REST URL). PremiseObject is the base type of a whole set of derived classes; thus the Dictionary actually contains a family of classes all derived from PremiseObject.
A key requirement is I want to try to 'guarantee' that no PremiseObjects get created OUTSIDE of the dictionary.
Solution: I have the following function for getting a object out of the dictionary. It either accesses the existing instance, or if it does not exist creates it:
public PremiseObject GetOrCreateServerObject(string premiseObjectType, string location)
{
PremiseObject po = null;
if (!premiseObjects.TryGetValue(location, out po))
{
string classname;
// Create an instance of the right PremiseObject derived class:
po = // gobbly-gook that is not relevant to this question.
premiseObjects.Add(location, po);
}
else
{
Debug.WriteLine("Already exists: {0}", location);
}
return po;
}
Callers do this:
DoorSensor door =
(DoorSensor)server.GetOrCreateServerObject("DoorSensor",
"http://xyz/FrontDoor");
Works great. But I think there's a pattern or design that would elegantly allow me to encapsulate the "single-instance of each object contained in the dictionary" more.
For example, callers could do this:
DoorSensor door = null;
if (!server.ServerObjects.TryGetValue("DoorSensor",
"http://xyz/FrontDoor",
out door))
Debug.WriteLine("Something went very wrong");
I'm not really what to call this pattern. My ServerObjects are "single-instanced" by location. And my GetOrCreateServerObject is like a factory that lazy creates.
But it's possible for instances to be created that don't get put into the dictionary, which could lead to problems.
Like I said, what I have works... Cheers!
UPDATE 1/26/2011 10:13PM -
I just realized a potential problem: On the server side the object represented by a location/URL can actually be multi-inherited. It is THEORETICALLY possible for an object to be both a DoorSensor and an DigitalRelay.
I currently don't care about any of those cases (e.g. for garage doors I simplified my example above; there really is no DoorSensor I exposed, just a GarageDoorOpener which includes BOTH properties for sensing (e.g. Status) and actuation (e.g. Trigger). But this puts a wrinkle in my whole scheme if I were to care. Since this project is just for me :-) I am going to declare I don't care and document it.
I would propose the following simple idea:
PremiseObject's constructor is declared internal.
A special factory object is responsible for creating (or returning an already created) instances. The dictionary is a part of the factory.
Clients are located in another assembly.
This way PremiseObjects can be created by clients only through the factory. This way you can guarantee that only single instance of object exists for each location.
A variant of the idea would be to declare the PremiseObject's constructor private, and declare the factory a friend; but (unlike C++) C# doesn't have a friend notion.
Ok you can probably avoid a parameter and a cast (in the consumer code any way) with a generic method.
public abstract class PremiseObject
{
protected PremiseObject()
{
}
public string Location { get; set; }
public static void GetSensor<T>(string location, out T sensor)
where T : PremiseObject, new()
{
PremiseObject so;
if(_locationSingltons.TryGetValue(location, out so))
{
sensor = (T) so; // this will throw and exception if the
// wrong type has been created.
return;
}
sensor = new T();
sensor.Location = location;
_locationSingltons.Add(location, sensor);
}
private static Dictionary<string, PremiseObject> _locationSingltons
= new Dictionary<string, PremiseObject>();
}
Then the calling code looks a bit nicer:
DoorSensor frontDoor;
PremiseObject.GetSensor("http://FrontDoor/etc", out frontDoor);
So I like that calling convention - if you want to stay away from throwing an exception you can change the return type to bool and indicate failure that way. Personally I wouls say that an exception is what you want.
You may prefer the call without the out parameter - but if you do that then you have to supply the type to the method call - anyway defining the factory method would look like this:
public static T GetSensor<T>(string location) where T : PremiseObject, new()
{
PremiseObject so;
if (_locationSingltons.TryGetValue(location, out so))
{
return (T)so; // this will throw and exception if the
// wrong type has been created.
}
T result = new T();
result.Location = location;
_locationSingltons.Add(location, result);
return result;
}
Then the calling code looks like this:
var frontDoor2 = PremiseObject.GetSensor<DoorSensor>("http://FrontDoor/etc");
I like both these approaches because nothing has to be repeated. The type of the PremiseObject only gets stated once - there is no need for a string defining the type.
If you want to be really, really sure that no instances of PremiseObject get created that aren't placed in the dictionary, you could make the constructors all private, and create a static constructor (for each subclass) that took as a parameter the Dictionary object you're referring to. This static constructor would check the dictionary object to make sure that there wasn't an existing instance, and then return either the new or the existing instance as required. So something like this:
public class PremiseObject
{
public static Dictionary<string, PremiseObject> PremiseObjects { get; private set; }
static PremiseObject()
{
PremiseObjects = new Dictionary<string, PremiseObject>();
}
}
public class DerivedPremiseObject : PremiseObject
{
private DerivedPremiseObject()
{
}
public static DerivedPremiseObject GetDerivedPremiseObject(string location)
{
DerivedPremiseObject po = null;
if (!PremiseObject.PremiseObjects.TryGetValue(location, out po))
{
po = new DerivedPremiseObject();
PremiseObject.PremiseObjects.Add(location, po);
}
return po;
}
}
And there are a variety of similar strategies you could use. The key is to somehow make the constructor private and only allow access to the constructor through a static method that enforces the logic of the class construction.
Perhaps you could make PremiseObject a singleton, then you wouldn't have to worry about each object in the dictionary beign a single instance?
In the general case, setting access modifiers on your constructors should do the trick of not allowing anyone external to create the objects (barring reflection). However, these would need to be internal, so anything else in the assembly would be able to instantiate them.
I suspect many of your requirements may be met by using an off the shelf dependency injection container that supports singleton instances. It feels close, but maybe not quite the same. (possibly StrutureMap, Ninject, Castle Windsor, or Unity in no particular order)

VS 2008 Intellisense for C# static dictionaries

I have the following in a C# class:
public static readonly SortedDictionary<string, string> Fields =
new SortedDictionary<string, string>
{ ... }
I was hoping there was a way to get Intellisense to provide prompts for all the keys defined in Fields. It supplies lists of the methods and properties in the class, including the Fields property, but when I go to access Fields[ or Fields[", it says nothing other than that I need to supply a string key. Is there a way to have it tell me a list of the string keys since this is a static class property that is not at all dynamic or changed after compilation?
If the keys are static wouldn't you be better off using an enumeration as your key instead of a string?
With an enumeration your compiler can tell you what the options are, but you can't do that with strings.
Do this instead:
public enum MyKeys
{
Key1,
Key2,
Key3
}
public static readonly SortedDictionary<MyKeys, string> Fields =
new SortedDictionary<MyKeys, string>
{ ... }
This will cause intellisense to pick up the enum type so you'll get the desired effect.
It seems to me that you assume that readonly there means that the dictionary won't ever change. This isn't the case - it only means that the value of the field (which is a reference to the dictionary) won't change (and even then it can still change while inside constructor, and can be null before it executes). The dictionary itself is quite mutable.
The best way for you to do this is probably to create public static readonly fields or properties.
If you need dictionary-like behavior, you should make the keys an enum as other people have suggested.
Remember that all of the dictionary class are mutable, which means that other code can add or remove items from your dictionary. The only way to prevent this would be to inherit a ReadOnlyCollection around a KeyedCollection and expose the indexer.
I have used static properties to do this.
What I have done for a Settings class of mine in order to get Intellisense was to create a code snippet that creates a static property. The code snippet is set up so that I enter the name of the setting and that same name is used in both the Property name and the lookup name.
Like this:
<Code Language="CSharp" Kind="method decl">
<![CDATA[ public static string $name$
{
get { return GetSetting("$name$", $default$); }
set { SaveSetting("$name$", value); }
}
]]>
</Code>
The GetSetting method would do something like this:
private static string GetSetting(string name)
{
if (!_Fields.ContainsKey(name))
_Fields.Add(name, default);
return _Fields[name];
}
This makes it really easy to add static properties and still get Intellisense.

Categories