Assume that 2 different methods - one static and one non-static - need an instance variable.
The variable is used 3-5 different times within the methods for comparison purposes.
The variable is NOT changed in any manner.
Also would the type of variable - String, Colection, Collection, etc. make any difference on how it should be coded.
What is the best/right way of using Instance Variable within a private method (static and non-static)?
Pass as method argument
Store locally by using the method to get the value - this.getClaimPropertyVertices();
Store locally by getting the value - this.claimPropertyVertices;
Use the instance variable directly in the method
When creating a local variable to store the value will the "final" keyword provide any advantages, if the variable will not be changed.
Edit 1: Based on a comment, I am adding additional information
The value cannot be created locally in the method. It has to come from the class or some other method accessed by the class.
My Solution Based on the Answers:
Based on the answer by #EricJ. and #Jodrell. I went with option 1 and also created it as a private static method. I also found some details here to support this.
When creating a local variable to store the value will the "final" keyword provide any advantages, if the variable will not be changed
In Java, final provides an optimization opportunity to the compiler. It states that the contents of the variable will not be changed. The keyword readonly provides a similar role in C#.
Whether or not that additional opportunity for optimization is meaningful depends on the specific problem. In many cases, the cost of other portions of the algorithm will be vastly larger than optimizations that the compiler is able to make due to final or readonly.
Use of those keywords has another benefit. They create a contract that the value will not change, which helps future maintainers of the code understand that they should not change the value (indeed, the compiler will not let them).
What is the best/right way of using Instance Variable within a private method (static and non-static)?
Pass as method argument
The value is already stored in the instance. Why pass it? Best case is this is not better than using the instance property/field. Worst case the JITer not inline the call, and will create a larger stack frame costing a few CPU cycles. Note: if you are calling a static method, then you must pass the variable as the static method cannot access the object instance.
Store locally by using the method to get the value - this.getClaimPropertyVertices();
This is what I do in general. Getters/setters are there to provide a meaningful wrapper around fields. In some cases, the getter will initialize the backing field (common pattern in C# when using serializers that do not call the object constructor. Don't get me started on that topic...).
Store locally by getting the value - this.claimPropertyVertices;
No, see above.
Use the instance variable directly in the method
Exactly the same as above. Using this or not using this should generate the exact same code.
UPDATE (based on your edit)
If the value is external to the object instance, and should not meaningfully be stored along with the instance, pass it in as a value to the method call.
If you write your functions with the static keyword whenever you can, there are several obvious benefits.
Its obvious what inputs effect the function from the signature.
You know that the function will have no side effects (unless you are passing by reference). This overlooks non-functional side effects, like changes to the GUI.
The function is not programtically tied to the class, if you decide that logically its behaviour has a better association with another entity, you can just move it. Then adjust any namespace references.
These benefits make the function easy to understand and simpler to reuse. They will also make it simpler to use the function in a Multi Threaded context, you don't have to worry about contention on ever spreading side effects.
I will cavet this answer. You should write potentially resuable functions with the static keyword. Simple or obviously non-resulable functionality should just access the private member or getter, if implemented.
Related
I stumbled upon a method today. I'm talking about: Array.Initialize().
According to the documentation:
This method is designed to help compilers support value-type arrays; most users do not need this method.
How does this method is responsible for making the compiler support value types? As far as I'm concerned this method just:
Initializes every element of the value-type Array by calling the default constructor of the value type.
Also, why is it public? I don't see myself with the need of calling this method, compilers already initialize arrays when created, so manually calling this method will be redundant and useless.
Even when my intention would be resetting the values of an array, I would still not call it, I would create a new one. array = new int[].
So, it seems that this method exist just for the sake of the compiler. Why is this? Can anyone give me some more details?
It's worth noting that the rules of .NET are different to the rules of C#.
There are things we can do in .NET that we can't do in C#, generally either because the code is not verifiable (ref return types for example) or because they could introduce some confusion.
In C# structs cannot have a defined parameterless constructor, and calling new SomeValueType() works by creating a zero-filled portion of memory (all fields therefore being 0 for numeric types, null for reference types, and the result of this same rule again for other value-types).
In .NET you can have a parameterless constructor on a value type.
It's probably a bad idea to do so. For one thing the rules about just when it is called and just when the memory of the value is zero-filled, and what happens upon assignment in different cases aren't entirely simple (e.g. new SomeValueType() will call it but new T() in a generic method where T is SomeValueType will not!). Life is simpler if the result of new SomeValueType() will always be zero-filling. That no doubt influenced the design of C# not allowing this even though .NET does.
For this reason, Array.Initialize() will never make sense on new arrays of any type that was written in C#, because calling the constructor and zero-filling is the same thing.
But by the same token, it's possible for a type to be written in another .NET language (at the very least, you can do it in CIL) that does have a parameterless constructor that actually has an effect. And for that reason its possible that a compiler for such a language would want its equivalent to new SomeValueType[3] to call that constructor on all the types in the array. And therefore it's sensible to have a method in the framework that allows such a fill to be done, so that a compiler for such a language can make use of it.
Also, why is it public?
So it can be called by code produced by such a hypothetical constructor even in a context where security restrictions prevent it from calling private methods of another assembly.
For me myself it looks like the Initialize() method runs through the array and recreates the Value Types within. So with a new array you get a new empty array and so you get with Array.Clear(), but with Array.Initialize() you get an Array full of fresh created Value Types (types and length based on the old array).
And that should be all of the difference.
Based on the CLR source, the method traverses each index of the array and initializes the value type on that index by calling the default constructor, similar to initobj IL instruction (I wonder what happens when the constructor throws an exception, though). The method is public because calling a private method directly from IL would make it a bit unverifiable.
Today's C# compilers do not initialize each element of the array when creating it, simply "set" each index to the default value of the type. C# 6 introduces implementing default constructors for value types (which were already supported by CLR), so this is needed for languages with different array creation semantics.
You can see the expected use in the test code:
https://github.com/dotnet/coreclr/blob/3015ff7afb4936a1c5c5856daa4e3482e6b390a9/tests/src/CoreMangLib/cti/system/array/arrayinitialize.cs
Basically, it sets an array of non-intrinsic value-types back to their default(T) state.
It does not seem like an amazingly useful tool, but I can see how it could be useful for zero'ing out arrays of non-intrinsic value data.
I've been working in C for the past couple of years and I've managed to get use to putting single-purpose, static variables near where they are used within my code.
While writing a very basic method that was in need of a method-scope static value, I was a bit surprised to find that the compiler didn't like that I tried to define a static object from within my method.
Googling has verified that this isn't possible within C#. Still, I'm curious why code, like the following, is completely off limits.
public int incrementCounterAndReturn()
{
static int i = 0;
return ++i;
}
Granted, this is a simplistic example that could be redefined for the same affect but that's beside the point. Method-scope, static values have their place and purpose. What design decisions have prevented such an implementation of static objects within C#?
We're on C# version 5.0 and it's 2013. I can only assume this isn't possible because of a design choice and not just because "that's complex and hard stuff to implement." Does anyone have any insider information?
The language design team is not required to provide a reason to not implement a feature. Rather, the person who wants the feature is required to make the case that the feature is the best possible way the design, implementation, test, and education teams can be spending their budgets. No one has ever successfully done so for your proposed feature.
Were I still on the design team and had this feature pitched I would point out that it is completely unnecessary. The feature in C is a known cause of developer confusion, particularly for novices, and the benefit of local vs type scope is tiny.
The underlying runtime does not provide method level static variables. In the CLR, all "static" data is defined on the type level, not method level. C# decided to not add this at the language level in its language design.
This is purely a design choice. VB.Net, which compiles to the same IL, does allow this via the Shared keyword in a Function or Sub statement (though it's handled via the compiler "promoting" the variable to a class level static variable).
Because in the CLR, static variables are associated with the TYPE. Storage for them is tied to the Type (class or stuct) they are associated with.
static variables are scoped to the class, not to an object instance. To make this work, your method must be declared static, and I believe your class must also be static (since instantiation is not relevant).
But the variable itself must be declared at the class level. C# doesn't allow you to create method-local static variables.
Worth noting: these kinds of maneuvers make it very difficult to unit test the method properly. Normally in C# one would make an ordinary class to hold such state; in fact, that's exactly how yield return works behind the scenes.
The .NET framework and languages were designed around the concept that anyone who is going to be compiling an assembly should be considered trustworthy enough to have access to all the code therein. From a semantic point of view, declaring a static variable foo within method bar would be equivalent to declaring a private static variable outside the method and accessing it within the method, provided only that one chooses as a name something which isn't used anywhere else. If one by convention combines the method name and meaning (e.g. bar_foo) one can generally avoid naming collisions pretty easily. Since the semantics are equivalent to having the variable declared outside the method, there's no need to have it declared inside.
I have a code like the following:
struct A
{
void SomeMethod()
{
var items = Enumerable.Range(0, 10).Where(i => i == _field);
}
int _field;
}
... and then i get the following compiler error:
Anonymous methods inside structs can not access instance members of 'this'.
Can anybody explains what's going on here.
Variables are captured by reference (even if they were actually value-types; boxing is done then).
However, this in a ValueType (struct) cannot be boxed, and hence you cannot capture it.
Eric Lippert has a nice article on the surprises of capturing ValueTypes. Let me find the link
The Truth About Value Types
Note in response to the comment by Chris Sinclair:
As a quick fix, you can store the struct in a local variable: A thisA = this; var items = Enumerable.Range(0, 10).Where(i => i == thisA._field); – Chris Sinclair 4 mins ago
Beware of the fact that this creates surprising situations: the identity of thisA is not the same as this. More explicitly, if you choose to keep the lambda around longer, it will have the boxed copy thisA captured by reference, and not the actual instance that SomeMethod was called on.
When you have an anonymous method it will be compiled into a new class, that class will have one method (the one you define). It will also have a reference to each variable that you used that was outside of the scope of the anonymous method. It's important to emphasize that it is a reference, not a copy, of that variable. "lambdas close over variables, not values" as the saying goes. This means that if you close over a variable outside of the scope of a lambda, and then change that variable after defining the anonymous method (but before invoking it) then you will see the changed value when you do invoke it).
So, what's the point of all of that. Well, if you were to close over this for a struct, which is a value type, it's possible for the lambda to outlive the struct. The anonymous method will be in a class, not a struct, so it will go on the heap, live as long as it needs to, and you are free to pass a reference to that class (directly or indirectly) wherever you want.
Now imagine that we have a local variable, with a struct of the type you've defined here. We use this named method to generate a lambda, and let's assume for a moment that the query items is returned (instead of the method being void). Would could then store that query in another instance (instead of local) variable, and iterate over that query some time later on another method. What would happen here? In essence, we would have held onto a reference to a value type that was on the stack once it is no longer in scope.
What does that mean? The answer is, we have no idea. (Please look over the link; it's kinda the crux of my argument.) The data could just happen to be the same, it could have been zeroed out, it could have been filled by entirely different objects, there is no way of knowing. C# goes to great lengths, as a language, to prevent you from doing things like this. Languages such as C or C++ don't try so hard to stop you from shooting your own foot.
Now, in this particular case, it's possible that you aren't going to use the lambda outside of the scope of what this refers to, but the compiler doesn't know that, and if it lets you create the lambda it has no way of determining whether or not you expose it in a way that could result in it outliving this, so the only way to prevent this problem is to disallow some cases that aren't actually problematic.
There are some .NET libraries which use methods for accessing object data instead of getters i.e HttpWebResponse.GetResponseStream().
Also there are examples of accessing an stream by a property i.e HttpResponse.OutputStream.
My question is when to use which form of access and why ?
See the FxCop rule: CA1024: Use properties where appropriate.
Good question. Although a property is little more than syntax sugar for a pair of get/set methods, there two should be used in different times.
Generally, you should use a property-style getter when:
The value to be returned represents field-like data (generally primitives/value types, but a reference to another domain object is also fine)
The calculation, if any, to produce that value is relatively cheap/side-effect free
Getting the same value twice will produce the same value given the same inputs
Generally, you should use a getter method when:
The returned object is created for the purpose (e.g. factory methods)
Evaluating the returned value requires side effects (e.g. touching a file system, database, or changing other values)
Getting the return type twice will produce two distinct results (i.e. two Streams, db connections, etc).
In a sentence, if conceptually speaking the value needed is something the object HAS, use a property. If the value needed is the result of something the object DOES, use a method.
Good question. This article brings up a few good points. In general, I use methods when the computation is expensive and properties when computation is not expensive (i.e. a stored value is returned).
My opinion which, I'm sure, will get to -10 real fast, is that you should only use properties for serialization. In all other cases explicit method call is preferable because when you look at it, you know that a method with possible side effects is being invoked.
I guess the "correct" (tm) answer is that when all your method would do is return the value, it is ok to use getter/setter, but if there is any work to do, use a method.
When you have automatic properties, C# compiler asks you to call the this constructor on any constructor you have, to make sure everything is initialized before you access them.
If you don't use automatic properties, but simply declare the values, you can avoid using the this constructor.
What's the overhead of using this on constructors in structs? Is it the same as double initializing the values?
Would you recommend not using it, if performance was a top concern for this particular type?
I would recommend not using automatic properties at all for structs, as it means they'll be mutable - if only privately.
Use readonly fields, and public properties to provide access to them where appropriate. Mutable structures are almost always a bad idea, and have all kinds of nasty little niggles.
Do you definitely need to create your own value type in the first place though? In my experience it's very rare to find a good reason to create a struct rather than a class. It may be that you've got one, but it's worth checking.
Back to your original question: if you care about performance, measure it. Always. In this case it's really easy - you can write the struct using an automatic property and then reimplement it without. You could use a #if block to keep both options available. Then you can measure typical situations and see whether the difference is significant. Of course, I think the design implications are likely to be more important anyway :)
Yes, the values will be initialized twice and without profiling it is difficult to say whether or not this performance hit would be significant.
The default constructor of a struct initializes all members to their default values. After this happens your constructor will run in which you undoubtedly set the values of those properties again.
I would imagine this would be no different than the CLR's practice of initializing all fields of a reference type upon instantiation.
The reason the C# compiler requires you to chain to the default constructor (i.e. append : this() to your constructor declaration) when auto-implemented properties are used is because all variables need to be assigned before exiting the constructor. Now, auto-implemented properties mess this up a bit in that they don't allow you to directly access the variables that back the properties. The method the compiler uses to get around this is to automatically assign all the variables to their default values, and to insure this, you must chain to the default constructor. It's not a particularly clever method, but it does the job well enough.
So indeed, this will mean that some variables will end up getting initialised twice. However, I don't think this will be a big performance problem. I would be very surprised it the compiler (or at very least the JIT) didn't simply remove the first initialisation statement for any variable that is set twice in your constructor. A quick benchmark should confirm this for you, though I'm quite sure you will get the suspected results. (If you by chance don't, and you absolutely need the tiny performance boost that avoidance of duplicate initialisation offers, you can just define your properties the normal way, i.e. with backing variables.)
To be honest, my advice would be not even to bother with auto-implemented properties in structures. It's perfectly acceptable just to use public variables in lieu of them, and they offer no less functionality than auto-implemented properties. Classes are a different situation of course, but I really wouldn't hesitate to use public variables in structs. (Any complex properties can be defined normally, if you need them.)
Hope that helps.
Don't use automatic properties with structure types. Simply expose fields directly. If a struct has an exposed public field Foo of type Bar, the fact that Foo is an exposed field of type Bar (information readily available from Intellisense) tells one pretty much everything there is to know about it. By contrast, the fact that a struct Foo has an exposed read-write property of Boz does not say anything about whether writing to Boz will mutate a field in the struct, or whether it will mutate some object to which Boz holds a reference. Exposing fields directly will offer cleaner semantics, and often also result in faster-running code.