C# compiler and caching of local variables - c#

EDIT: Oops - as rightly pointed out, there'd be no way to know whether the constructor for the class in question is sensitive to when or how many times it is called, or whether the object's state is changed during the method, so it would have to be created from scratch each time. Ignore the Dictionary and just consider delegates created in-line during the course of a method :-)
Say I have the following method with Dictionary of Type to Action local variable.
void TakeAction(Type type)
{
// Random types chosen for example.
var actions = new Dictionary<Type, Action>()
{
{typeof(StringBuilder), () =>
{
// ..
}},
{typeof(DateTime), () =>
{
// ..
}}
};
actions[type].Invoke();
}
The Dictionary will always be the same when the method is called. Can the C# compiler notice this, only create it once and cache it somewhere for use in future calls to the method? Or will it simply be created from scratch each time? I know it could be a field of the containing class, but it seems neater to me for a thing like this to be contained in the method that uses it.

How should the C# compiler know that it's "the same" dictionary every time? You explicitly create a new dictionary every time. C# does not support static local variables, so you have to use a field. There's nothing wrong with that, even if no other method uses the field.
It would be bad if the C# compiler did things like that. What if the constructor of the variable uses random input? :)

Short answer: no.
Slightly longer answer: I believe it will cache the result of creating a delegate from a lambda expression which doesn't capture anything (including "this") but that's a pretty special case.
Correct way to change your code: declare a private static readonly variable for the dictionary.
private static readonly Dictionary<Type,Action> Actions =
new Dictionary<Type, Action>()
{
{ typeof(StringBuilder), () => ... },
{ typeof(DateTime), () => ... },
}
void TakeAction(Type type)
{
Actions[type].Invoke();
}

For any compiler to be able to do this, it would have to have some way to have guarantees for the following issues:
Constructing two objects the exact same way produces identical objects, in any way, except for their location in memory. This would mean that the object constructed the second time would be no different from the first one, as opposed to say, caching an object of the Random typ.e
Interacting with the object does not change its state. This would mean that caching the object would be safe and would not change the behavior of subsequent calls. This would for instance rule out modifying the dictionary in any way.
The reason for this is that the compiler would have to be able to guarantee that the object it constructed the first time would be equally usable the next time around without having to recreate it.
Now, that C# and .NET does not have mechanisms for making these guarantees is probably not the reason why support for this kind of optimization isn't done by the compiler, but these would have to be implemented first. There could also be other such guarantees the compiler would need to have before it could do it that I don't know of.
The change that Jon Skeet has suggested is basically the way to say that I know that these two guarantees hold for my code, and thus you take control over the situation yourself.

That dictionary will be created anew each time; otherwise, for example, you could put other things into the dictionary, and the intent would be lost.

Related

C#: What happens when assigning auto-property?

I learned that in C# there is this thing called autoproperty, which ist normally automatically generated by the compiler if i declared a variable like:
public List myList { get; set; }
public class MyClass
{
private List<int> myList;
public List<int> MyList
{
get
{
return this.myList;
}
set
{
this.myList = value;
}
}
}
It lets me access the variable like:
List<int> a = myInstance.MyList;
So it works like a function, but is called like a normal object.
But what is really assigned on a ? Is there assigned a "deep link" on the object myList or is there assigned something like a "functor" on the get function?
What i mean is, if i work with a, will the get function be called again everytime?
The reason why I'm asking: If I'm using this in a multithreaded case with some locking of the object in the get and set function I don't want to bypass the locking. So if I first assign myList on a and then work with it, it won't be locked anymore? Am I right?
But what is really assigned on a?
The type of a is List<int>, and lists are reference types, so the variable contains a reference to a list. C# doesn't lie to you. The type of the variable is the type of the variable.
it works like a function, but is called like a normal object.
This sentence makes no sense and it indicates to me that you have some misunderstanding of how C# works. "Objects" are not things that are "called" unless they are delegates. It sounds like you are confusing properties, variables, objects and delegates. Learn what those things are. It will be difficult to be successful in C# programming if you do not know the correct names of all the parts.
I think what you intended to say is that a property is a member which is accessed like a field, but reads and writes of the property are implemented as calls to member access methods.
What i mean is, if i work with a, will the get function be called again everytime?
You could answer this question for yourself by trying it:
myInstance.MyList = new List<int> { 10, 20, 30 };
List<int> a = myInstance.MyList;
myInstance.MyList = new List<int> { 100, 200, 300 };
Console.WriteLine(a[0]);
If a fetches the property again, it should be 100. If it does not, it should be 10. Make a prediction about what will happen, and then try it and see if you were right.
If I'm using this in a multithreaded case with some locking of the object in the get and set function I don't want to bypass the locking. So if I first assign MyList to a and then work with it, it won't be locked anymore? Am I right?
Yes. I will take this opportunity to point out that it is an extremely poor programming practice to make a public interface that exposes an object that must be locked. Better options are:
Do not write multithreaded programs. It's really hard to get them right.
If you must, do not write multithreaded programs that share memory across threads.
If you must share memory, use threadsafe collections, always.
Properties are just better named List<int> getValue() and setValue(List<int> value) function pair. There are some minor properties:
they appear on reflection
they can be declared in interfaces/abstract classes
they are used like a field, except in rare cases (out and ref parameters)
But overall that is all there is to them.
Autoimplement proeprties are the same as manual ones, except the backing field has no name (you could use in your code), so there is 0 chance to accidentally access the backingfield.
One of the most important rules with Properties is to not write the Backing fields, especially in class code. And just lower casing it does not work. I lost track how often I coded so fast, a Upper case did not stick. For reliable naming, append a underscore to the backing field. _MyList and MyList are pretty hard to mix up. MyList and myList are easy to mix up.
When you assign myInstance.MyList to a, you call the MyList get Property which copies the reference myList into a. If you then work with a you will be working directly with the List referred to by the private myList. You will only go via the get Property if you actually call it.
This is basically losing the private nature of myList. If you want to force the caller to go via functions which do things like locking then you will have to write functions for the operations you want to allow, like adding to the List, without exposing the actual List to the caller.
There's no need to do this in C# for thread safe operations - you should use the Concurrent Collections which implement these operations for free.

Good reasons for static methods?

I use static methods for things I really MEANT to be static. I use ReSharper for better code quality. Sometimes ReSharper suggests that a method can be made static.
When I got the following class:
public class WhatEverClass {
private string DoSomethingFancy(string input)
{
string fancyStuff;
// Fancy Stuff here
return fancyStuff;
}
public WhatEverClass() {
string awesome=DoSomethingFancy("some fancy string");
}
}
ReSharper might say "DoSomethingFancy can be made static".
I know it could be made static, but is there a good reason to really do this? Or should I just ignore these suggestions?
By defining a method static, so a procedure that computes something, you manifest an intent to a consumer of your API about statelessness of your function.
When we use static function, we do not expect it saves a state of computation or some computed internal value somewhere in it's internal static private variables, so the next call to that function may have different result even with the same parameters passed during the first call.
In short: whenever you see a function that just executes an action over parameter and not preserve some state, it is a good candidate for making it static.
If your method doesn't need to say or change the state of an instanciated object, then it should be static.
The usual notion is , if you are not creating an instance of anything, you could declare it static. As to where it should be used, ReSharper gives you suggestions based on standard programming practices. However, i take 'standard programming practices' with a grain of salt. Its a matter of personal programming preference for some. Here is a detailed reference on the topic :
http://msdn.microsoft.com/en-us/library/79b3xss3.aspx
Because you will invoke the WhatEverClass() method from outside the class by creating WhatEverClass instance. So the value for every instance will be different, because the variable is local, and will be created every time you create an instance of the class.
But if you want to keep the same value for all instances, then you can make it static so it will be created once in a memory and all instances will use it.
Beware the consequences of making a method static!
By making your method static, you make it that much harder for consumers to stub out your implementation of the algorithm and replace it with one of their own (obviously if the method is private you have no such worries).
Consumers of your static method have your implementation baked in to their code - they cannot use dependency injection to resolve a specific instance of your algorithm (without a bit of work). This makes their system that much harder to test, and in general lends itself to a less extensible code base.
If the method DoSomethingFancy does not use anything in the object WhatEverClass then it should, in my book, be made static since it does not in fact have anything to do with the object in which it is used.

Why do implicit property names only work in anonymous objects?

What is the limitation of
public class A
{
public string Stuff {get;set;}
}
...
repository.GetAll().Select(x=> new A { x.Stuff });
That doesn't work. You have to add
{ Stuff = x.Stuff }
repository.GetAll().Select(x=> new { x.Stuff });
But this works. It creates an anon class with a very similar definition to class A.
Conceptually I don't see a big difference in what is going on here. Anyone shed some light?
The short answer - the C# compiler and language team didn't implement it this way - they either didn't think of it (unlikely) or decided that it was not a good idea....
repository.GetAll().Select(x=> new A { x.Stuff });
That doesn't work. You have to add
This is an object initializer. This works by calling the default constructor on an object, and then matching property names to a value, ie: Stuff = x.Foo, and is really just a shortcut for matching properties, so the syntax is really just "short hand" for:
A tmp = new A();
tmp.Stuff = x.Stuff;
Now, I suppose the compiler team could have assumed that an initialization statement with no left hand side on the equation should search for a matching property where the name matched and the type was implicitly convertible, but I suspect this would fall into the realm of "flirting with the bad idea list" if or when it would've been discussed by the language team. In general, C# is fairly explicit in its syntax, and this would be loosening that up a bit in a way that requires two separate matches (name + type) and would be non-obvious in many scenarios. Since you're working with a public API here (A), it'd also be very easy for a refactoring in either side (A or whatever type "x" is defined as being) to break this completely.
Finally, this also isn't really necessary - if you want an instance of A to be constructed this way, just add a constructor with an overload (which is safer in many ways in any case), and use:
repository.GetAll().Select(x=> new A(x.Stuff));
This makes the intention and meaning very explicit, and takes out the brittle maintainability.
repository.GetAll().Select(x=> new { x.Stuff });
This is doing something completely different - here, you're initializing an anonymous type, and letting the compiler completely determine the type names and types for you. I suspect this was determined to be "safe" since you're never really working with a public API - anonymous types aren't really supposed to "leak" out of the method where it's defined. The risk of having a refactoring change a property name and effectively change values, etc, gets dramatically reduced and isolated to a single method in this case, which in turn keeps this "automatic" naming feature lower risk overall. Also, there isn't an easy alternative here, as you can't define constructors on anonymous types, so there wouldn't be a simple way to have a concise syntax in this case. This adds benefit without introducing a lot of risk.
One possible reasoning: if implicit property assignment would be allowed for real types than change in item of repository (i.e. x.Stuff renamed to x.Other) would cause compile time error in very surprising place as new property no longer match A.Stuff.

C#: Is it possible to use expressions or functions as keys in a dictionary?

Would it work to use Expression<Func<T>> or Func<T> as keys in a dictionary? For example to cache the result of heavy calculations.
For example, changing my very basic cache from a different question of mine a bit:
public static class Cache<T>
{
// Alternatively using Expression<Func<T>> instead
private static Dictionary<Func<T>, T> cache;
static Cache()
{
cache = new Dictionary<Func<T>, T>();
}
public static T GetResult(Func<T> f)
{
if (cache.ContainsKey(f))
return cache[f];
return cache[f] = f();
}
}
Would this even work?
Edit: After a quick test, it seems like it actually works. But I discovered that it could probably be more generic, since it would now be one cache per return type... not sure how to change it so that wouldn't happen though... hmm
Edit 2: Noo, wait... it actually doesn't. Well, for regular methods it does. But not for lambdas. They get various random method names even if they look the same. Oh well c",)
You can use any type of object, as long as it is an instance. That even being a delegate, but I do not recommend using delegates as keys because they are not designed for that. I'm not sure that independently created delegates produce the same hash code, even less if they can be compared (equatable).
This might be a stretch, but using the Dynamic Language Runtime (IronPython, etc) you could definitely run arbitrary code snippets from a dictionary.
Then you could run the code on the fly as needed, cache the result the first time, and use the cached result for all future calls.
If you had a lot of computations, I bet this would end up performing pretty well. It's all situational though, and I'm not sure exactly what you're trying to achieve. :)

Value assignment for reference type in C#

What is the proper way to implement assignment by value for a reference type? I want to perform an assignment, but not change the reference.
Here is what I'm talking about:
void Main()
{
A a1 = new A(1);
A a2 = new A(2);
a1 = a2; //WRONG: Changes reference
a1.ValueAssign(a2); //This works, but is it the best way?
}
class A
{
int i;
public A(int i)
{
this.i = i;
}
public void ValueAssign(A a)
{
this.i = a.i;
}
}
Is there some sort of convention I should be using for this? I feel like I'm not the first person that has encountered this. Thanks.
EDIT:
Wow. I think I need to tailor my question more toward the actual problem I'm facing. I'm getting a lot of answers that do not meet the requirement of not changing the reference. Cloning is not the issue here. The problem lies in ASSIGNING the clone.
I have many classes that depend on A - they all share a reference to the same object of class A. So, whenever one classes changes A, it's reflected in the others, right? That's all fine and well until one of the classes tries to do this:
myA = new A();
In reality I'm not doing new A() but I'm actually retrieving a serialized version of A off the hard drive. But anyways, doing this causes myA to receive a NEW REFERENCE. It no longer shares the same A as the rest of the classes that depend on A. This is the problem that I am trying to address. I want all classes that have the instance of A to be affected by the line of code above.
I hope this clarifies my question. Thank you.
It sounds like you're talking about cloning. Some objects will support this (via ICloneable) but most won't. In many cases it doesn't make sense anyway - what does it mean to copy a FileStream object? ICloneable is generally regarded as a bad interface to use, partly because it doesn't specify the depth of the clone.
It's better to try to change your way of thinking so this isn't necessary. My guess is that you're a C++ programmer - and without wishing to cast any judgements at all: don't try to write C# as if it's C++. You'll end up with unidiomatic C# which may not work terrible well, may be inefficient, and may be unintuitive for C# developers to understand.
One option is to try to make types immutable where possible - at that point it doesn't matter whether or not there's a copy, as you wouldn't be able to change the object anyway. This is the approach that String takes, and it works very well. It's just a shame that there aren't immutable collections in the framework (yet).
In your case, instead of having the ValueAssign method, you would have WithValue which would return a new instance with just the value changed. (Admittedly that's the only value available in your case...) I realise that this sort of copying (of all but the property that's about to change) goes against what I was saying about copying being somewhat unidiomatic in C#, but it's within the class rather than an outside body deciding when to copy.
I suspect I'm not explaining this terribly well, but my general advice is to design around it rather than to try to explicitly copy all over the place.
I believe you should be using a struct instead of a class than, as structs work by value and not by reference.
For what you want to do, I think A.ValueAssign(otherA) is the best way.
Given that you want to have one reference of A around, ensuring that the reference isn't destroyed is key.
Wouldn't you also be served by using a singleton pattern here as well?
One approach is to use a copy constructor. e.g.,
MyClass orig = ...;
MyClass copy = new MyClass(orig);
Where you copy the elements of MyClass. Depending on how many reference types the class contains this might involve recursive use of copy constructors.
We have cases where we do exactly what you are talking about. We have many objects referencing a particular instance of an object and we want to change the instance of the object so that every object referencing that existing instance see the change.
The pattern we follow is almost what you have - just the names are different:
class A
{
int i;
public A(int i)
{
this.i = i;
}
public void Copy(A source)
{
this.i = source.i;
}
}
Others have suggested cloning in their answer, but that's only part of the deal. You also want to use the results of a (possibly deep) clone to replace the contents of an existing object. That's a very C++-like requirement.
It just doesn't come up very often in C#, so there's no standard method name or operator meaning "replace the contents of this object with a copy of the contents of that object".
The reason it occurs so often in C++ is because of the need to track ownership so that cleanup can be performed. If you have a member:
std::vector<int> ints;
You have the advantage that it will be properly destroyed when the enclosing object is destroyed. But if you want to replace it with a new vector, you need swap to make that efficient. Alternatively you could have:
std::vector<int> *ints;
Now you can swap in a new one easily, but you have to remember to delete the old one first, and in the enclosing class's destructor.
In C# you don't need to worry about that. There's one right way:
List<int> ints = new List<int>();
You don't have to clean it up, and you can swap in a new one by reference. Best of both.
Edit:
If you have multiple "client" objects that need to hold a reference to an object and you want to be able to replace that object, you would make them hold a reference to an intermediate object that would act as a "wrapper".
class Replaceable<T>
{
public T Instance { get; set; }
}
The other classes would hold a reference to the Replaceable<T>. So would the code that needs to swap in a replacement. e.g.
Replaceable<FileStream> _fileStream;
It might also be useful to declare an event, so clients could subscribe to find out when the stored instance was replaced. Reusable version here.
You could also define implicit conversion operators to remove some syntax noise.
In several WinForms based applications, I've needed similar functionality, in my case to allow a data entry form to work on a copy of the object, information from which is copied onto the original object only if the user elects to save the changes.
To make this work, I brought across an idea from my Delphi days - the Assign() method.
Essentially, I wrote (well, ok, generated) a method that copies across properties (and list contents, etc etc) from one instance to another. This allowed me to write code like this:
var person = PersonRespository.FindByName("Bevan");
...
var copy = new Person();
copy.Assign(person);
using (var form = new PersonDataEntryForm(copy))
{
if (form.ShowAsModelessDialog() == MessageReturn.Save)
{
person.Assign(copy);
}
}
Changes made within the dialog are private until the user chooses to save them, then the public variable (person) is updated.
An Assign() method for Person might look like this:
public void Assign(Person source)
{
Name = source.Name;
Gender = source.Gender;
Spouse = source.Spouse;
Children.Clear();
Children.AddRange( source.Children);
}
As an aside, having an Assign() method makes a copy-constructor almost trivially easy to write:
public Person(Person original)
: this()
{
Assign(original);
}
I wish there was a "second best" answer option, because anyone who mentioned Observer deserves it. The observer pattern would work, however it is not necessary and in my opinion, is overkill.
If multiple objects need to maintain a reference to the same object ("MyClass", below) and you need to perform an assignment to the referenced object ("MyClass"), the easiest way to handle it is to create a ValueAssign function as follows:
public class MyClass
{
private int a;
private int b;
void ValueAssign(MyClass mo)
{
this.a = mo.a;
this.b = mo.b;
}
}
Observer would only be necessary if other action was required by the dependent objects at the time of assignment. If you wish to only maintain the reference, this method is adequate. This example here is the same as the example that I proposed in my question, but I feel that it better emphasizes my intent.
Thank you for all your answers. I seriously considered all of them.
I had the exact same problem.
The way I solved it was by putting the object that everything is referencing inside another object and had everything reference the outer object instead. Then you could change the inner object and everything would be able to reference the new inner object.
OuterObject.InerObject.stuff
It's not possible to overload the assignment operator in c# as it would be in c/c++. However even if that was an option I'd say your trying to fix the symptom not the problem. Your problem is that the assignment of a new reference is breaking code, why not just assign the read values to the original reference? and If you are affraid that others might new and assign make the object into a singleton or similar so that it can't be altered after creation but the reference will stay the same
If I got it right, you are talking about proper Singleton deserialization.
If you are using .Net native serialization then you might take a look at the MSDN ISerializable example. The example shows exactly that - how to override ISerializable.GetObjectData to return the same instance on each call.
If you are using Xml serialization (XmlSerializer), then you manually implement IXmlSerializable in your object's parent class, and then take care to get a single instance each time.
A simplest way would be to ensure this in your parent property's setter, by accessing some kind of a static cache. (I find this pretty dirty, but that's an easy way to do it).
For example:
public class ParentClass
{
private ReferencedClass _reference;
public ReferencedClass Reference
{
get
{
return _reference;
}
set
{
// don't assign the value, but consult the
// static dictionary to see if we already have
// the singleton
_reference = StaticCache.GetSingleton(value);
}
}
}
And then you would have a static class with some kind of a dictionary where you could quickly retrieve the singleton instance (or create it if it doesn't exist).
Although this may work for you, I also agree with the others that this is rarely the best (or only) way to do it. There is surely a way to refactor your code so that this becomes unnecessary, but you should provide some additional info about what is the intended usage, where is this data accessed from, or simply why do classes really need to reference a single object.
[Edit]
Since you are using a static cache similar to a singleton, you should take care to implement it properly. That means several things:
Your cache class should have a private constructor. You don't want anyone to create a new instance explicitly - this is not an option when using singletons. So this means you should expose some public static property like Cache.Instance which will always return the reference to the same private object.
Since the constructor is private, you are sure that only Cache class can create the instance during initialization (or first update).
Details on implementing this pattern can be found at http://www.yoda.arachsys.com/csharp/singleton.html (which is also a great thread-safe implementation).
When all you object have the same instance, then you can simply notify cache to update the single private instance (e.g. call Cache.Update() from somewhere). This way you can update the only instance which everyone is using.
But it still not clear from your example how exactly you are notifying your clients that the data has been updated anyway. An event-driven mechanism would work better, as it would allow you to decouple your code - Singletons are evil.
What if you did this:
public class B
{
B(int i) {A = new A(i);}
public A A {get; set;}
}
...
void Main()
{
B b1 = new B(1);
A a2 = new A(2);
b1.A = a2;
}
Throughout your program, references to A should only be accessed via an instance of B. When you reassign b.A, you're changing the reference of A, but that doesn't matter because all of your external references are still pointing to B. This has a lot of similarities with your original solution, but it allows you to change A any way you want without having to update its ValueAssign method.

Categories