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
Related
In implementing a Service Locator, I've come across something I'm confused about with regards to reference types.
In the code below, I have a static class ServiceLocator which exposes 2 static methods, GetService and ProvideService - get returns the current service, and provide takes a new service as an argument and assigns it to the current service variable. If the provided service is null, it assigns currentService to a static defaultService initialised at the start of the class declaration. Simple stuff:
public static class ServiceLocator {
private static readonly Service defaultService = new Service();
private static Service currentService = defaultService;
public static Service GetService() {
return currentService;
}
public static void ProvideService(Service service) {
currentService = service ?? defaultService;
}
}
What i'm confused about is this: I have a separate class which stores a reference to the currentService at the start of its class declaration in the variable named referenceToCurrentServiceAtStart. When I provide the service locator with a new Service instance to update the current service, referenceToCurrentServiceAtStart appears instead to maintain the reference to defaultService:
public class ClassThatUsesService {
private Service referenceToCurrentServiceAtStart = ServiceLocator.GetService();
private static ClassThatUsesService() {
ServiceLocator.ProvideService(new Service());
// this variable appears to still reference the defaultService
referenceToCurrentServiceAtStart != ServiceLocator.GetService()
}
}
So the references appear to follow this kind of chain:
referenceToCurrentServiceAtStart -> defaultService -> (Service in memory)
Which is understandable, since referenceToCurrentServiceAtStart simply copies the currentService reference. However, the behaviour I'm looking for/would like is for referenceToCurrentServiceAtStart to always reference whatever currentService references, so it's updated by Provide(). Something more akin to:
referenceToCurrentServiceAtStart -> currentService -> (Service> in memory)
So, is this behaviour possible? I'm really unsure of how I'd achieve this kind of reference behaviour. I'm new to C# so it's very possible there's some obvious language feature I'm clueless about. Any help would be greatly appreciated.
is this behaviour possible?
No, not as you've described it. As you're already aware, all you get is a copy of the original reference. Changing the original reference doesn't change the copy, any more than copying the value of an int variable to another would allow you to later change the original and have the copy change:
int original = 17;
int copy = original;
original = 19;
// "copy" is still 17, of course!
If you want to always have the current value of the reference in ServiceLocator, then you should just always retrieve the value from that class, rather than using a local field. In your above example, you might indirect through a property, e.g.:
public class ClassThatUsesService {
private Service referenceToCurrentServiceAtStart => ServiceLocator.GetService();
}
It's a one character change (the = becomes =>), but don't be fooled. It's a significant change in implementation. What you wind up with instead of a field, is a read-only property (i.e. has only a get method and no set method), where that property's get method calls the ServiceLocator.GetService() method and returns the result.
Personally, I wouldn't bother. Unless you have some very strong expectation that the implementation of referenceToCurrentServiceAtStart will change in the future, you should just call ServiceLocator.GetService() directly. Don't even have the referenceToCurrentServiceAtStart property. Since the code expects to always get the current value, the best way to ensure that is to just always get the current value, straight from the class where that value is stored.
Finally, I'll take the opportunity to show a scenario that is similar to what you're asking, but not exactly. In particular, because you're trying to store the reference in a class field, the above is how you need to do it. But, the latest C# has "reference return values", which must be stored in "ref locals". Since you want to reference a static field, which is guaranteed to always exist, you can in fact return a reference to the field, store that in a local, and when you retrieve the local variable's value, it will always have whatever is in the field, because it's a reference to the field, not a copy of it.
You can see the example in the documentation (see links above), but here's another example that is more similar to what you're doing:
class Program
{
static void Main(string[] args)
{
// stores a reference to the value returned by M1(), which is to say,
// a reference to the B._o field.
ref A a1 = ref B.M1();
// Keep the original value, and create a new A instance
A original = a1, a2 = new A();
// Update the B._o field to the new A instance
B.M2(a2);
// Check the current state
Console.WriteLine($"original.ID: {original.ID}");
Console.WriteLine($"a1.ID: {a1.ID}");
Console.WriteLine($"a2.ID: {a2.ID}");
}
}
class A
{
private static int _id;
public int ID { get; }
public A()
{
ID = ++_id;
}
}
class B
{
private static A _o = new A();
public static ref A M1()
{
// returns a _reference_ to the _o field, rather than a copy of its value
return ref _o;
}
public static void M2(A o)
{
_o = o;
}
}
When you run the above, you'll get this output:
original.ID: 1
a1.ID: 2
a2.ID: 2
In other words, the variable a1 winds up yielding the same value found in a2, which is the new object passed to the B.M2() method to modify the B._o field, while the original copy of the B._o field value remains a reference to the original object that field referenced.
This doesn't work in your case, because the ref value that's returned has to be stored in a ref local. You can't put it into a class field. But it's similar enough to your scenario that I wanted to mention it, in case you want to change your design to allow that, or want to use that technique in some other scenario that does work in that way.
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; }
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.
Rephrased the question. Scroll down for the original
Ok, maybe I should have given you the whole picture. I have many classes which look like this:
public class Movement : Component
{
private Vector3 linearVelocity;
public Vector3 LinearVelocity
{
get
{
return linearVelocity;
}
set
{
if (value != linearVelocity)
{
linearVelocity = value;
ComponentChangedEvent<Movement>.Invoke(this, "LinearVelocity");
}
}
}
// other properties (e.g. AngularVelocity), which are declared exactly
// the same way as above
}
There are also classes called Transform, Mesh, Collider, Appearance, etc. all derived from Component and all have nothing but properties which are declared as described above. What is important here is to invoke the ComponentChangedEvent. Everything works perfectly, but I was looking for a way where I don't have to rewrite the same logic for each property again and again.
I had a look here and liked the idea of using generic properties. What I came up with looks like this:
public class ComponentProperty<TValue, TOwner>
{
private TValue _value;
public TValue Value
{
get
{
return _value;
}
set
{
if (!EqualityComparer<TValue>.Default.Equals(_value, value))
{
_value = value;
ComponentChangedEvent<TOwner>.Invoke(
/*get instance of the class which declares value (e.g. Movement instance)*/,
/*get name of property where value comes from (e.g. "LinearVelocity") */);
}
}
}
public static implicit operator TValue(ComponentProperty<TValue, TOwner> value)
{
return value.Value;
}
public static implicit operator ComponentProperty<TValue, TOwner>(TValue value)
{
return new ComponentProperty<TValue, TOwner> { Value = value };
}
}
Then I would use it like this:
public class Movement : Component
{
public ComponentProperty<Vector3, Movement> LinearVelocity { get; set; }
public ComponentProperty<Vector3, Movement> AngularVelocity { get; set; }
}
But I am not able to get the instance where LinearVelocity comes from nor it's name as string. So my question was, if all of this is possible...
But it seems that I have no option other than keep doing it the way I was, writing this logic for each property manually.
Original Question:
Get instance of declaring class from property
I have a class with a property:
public class Foo
{
public int Bar { get; set; }
}
In another context I have something like this:
Foo fooInstance = new Foo();
DoSomething(fooInstance.Bar);
Then, in DoSomething I need to get fooInstance from having nothing but parameter. From the context, it is save to assume that not any integers are passed into DoSomething, but only public properties of ints.
public void DoSomething(int parameter)
{
// need to use fooInstance here as well,
// and no, it is not possible to just pass it in as another parameter
}
Is that possible at all? Using reflection, or maybe a custom attribute on the property Bar?
Why do you want to send just a property to DoSomething, send it the whole object :), so it would become,
DoSomething(fooInstance);
Your function will then accept object instead of parameter. You can use an overload of this function to make sure that old code doesn't break.
There are several ways to deal with implementing INotifyPropertyChanged. You're doing almost the same thing, except you don't implement the interface and raise the event in a different way. But all of the solutions apply for you too.
Like you do, call a method with a string parameter: OnPropertyChanged("Property").
Call a method with a lambda that uses the property: OnPropertyChanged(() => Property). The advantage of this is that it's compile-time checked for typos and refactoring-friendly.
Use caller information to inject the name of the property: OnPropertyChanged(). This will work in C# 5.
Use something like Castle DynamicProxy to create a derived class at runtime that will call the method for you. This means you need to make your properties virtual and that you need to create instances of the class only through Castle.
Use an AOP framework to modify the code of your properties after compilation to call the method.
there's no way to get fooInstance from parameter. parameter is passed by value, and is only a copy of the value of fooInstance.Bar, it no longer has anything to do with fooInstance
That being said, the obvious solution is to write DoSomething like this
public void DoSomething(Foo parameter)
{
// need to use fooInstance here as well,
// and no, it is not possible to just pass it in as another parameter
}
Property is just a field, which returns reference to some object on heap (i.e. its address). If property is not of reference type, it returns value of object.
So, when you do something like
DoSomething(fooInstance.Bar);
You just passing address of object Bar to method.
If Bar is reference type (i.e. class). Imagine that Mr.Foo has an address of Mr.Bar (462 for Marion County, Indiana). Mrs.CLR asks Mr.Foo for address of Mr.Bar. And then tells this address to somebody who needs address of Mr.Bar. How somebody will know, that CLR asked Foo about address of Bar? He received only an address 462 for Marion County, Indiana.
In case of value objects (int, double, structs etc), Mr.Foo has a cool mp3 track named Bar. Mrs. CLR creates a copy of that mp3 track and sends it to somebody. How somebody will know, that his mp3 track Bar is a copy of Mr.Foo's track?
So, if you want somebody to know about Mr.Foo, you need to pass an address of Mr.Foo to him:
DoSomething(fooInstance);
With this address somebody can visit Mr.Foo and ask him about address of Mr.Bar, or create a copy of his mp3 track :)
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.