We cannot specify access modifiers for fields in a method, The reason I suspect for this is that the fields inside a method (i.e local variables) should have scope only inside that particular method so there is no need to specify the access modifiers.
class Program
{
public static void Main()
{
int Y;
Test(out Y);
}
private static void Test(out int X)
{
X = 17;
}
}
Question:
If scope of method field is within that method then how ref and out works across methods? I know they are passed by reference but how CLR can pass that variables address(reference) when its scope is limited to that particular method?
If scope of method field is within that method then how ref and out works across methods? I know they are passed by reference but how CLR can pass that variables address(reference) when its scope is limited to that particular method?
The variable address is not bound to it's scope.When you have the address, you can access the object in that address from whereever you want.This address is used whenever you make changes in the ref or out parameter. Compiler uses that to access and manipulate the actual data.So the scope has nothing to do with it.
It makes no sense to try and declare a private variable in a method . Because by default you can't acces a variable outside a method. Variables that you declare in a method are called local variables. So it wouldn't make any sense to be allowed to give it an acces modifier
These are local variables which are accessible in the method's code block (methodName{..code-block-here..}) scope only and you can't specify any other accessibility level to them - there is no sence to access them from the outside world.
Modifiers are meant to control external class access to variables.
For example, you might not want any class other than your own to access a variable, or you just want subclasses and classes in the same package to access it. Thats the job of modifiers.
A method variable, however, is not accessible by anything outside of that method, and won't live for longer than the time it takes for the method to complete, so there really no point to having modifiers inside the method. The variable access is fixed as its scope is very limited.
Related
public Tiles[,] tiles;
Is a global variable, an array, I dare say, the size of which is yet to be discovered. That's why I wish to initialize it inside a function. Alas, after the function is done, so is the variable. How doth one fix that?
If you wrote something like this:
public void Init()
{
tiles = new Tiles[2, 5];
}
The instantiated array still exists. Because it was stored in the tiles variable, which is in the class scope, it's lifetime is that of the object. Thus, you have nothing to worry about. Subsequently accessing the tiles field (should have been a property...) will use the object created in Init.
As an aside, that variable is not global, it is scoped to the class. Aside from statics, there is no such thing as a "global" variable in C# (and even static members are still scoped to their class, which does have a global instance).
Note
Jon Skeet's answer indicates excellent practice for initializing variables, among other things. I am primarily trying to address the misunderstanding of variable scope/lifetime in this answer.
Sounds like you just want:
private readonly Tile[,] tiles = InitializeTileArray();
...
private static readonly Tile[,] InitializeTileArray()
{
Tile[,] array = ...;
// Whatever you want here
return array;
}
Note that the method has to be static - you can't call an instance method from a field initializer. If you need to do that, you need to put the call into your constructor instead.
Note that I've made the field itself private - and readonly, which may not be appropriate for you. I would recommend always (or at least nearly always) using private fields - you can expose the data via properties and indexers.
I've tried searching this but I cant find a clear answer to my question.
When can you actually alter a static variable?
From my understanding you can only change it within the static constructor. But I'm not sure, any help on this would be greatly appreciated.
Static fields/properties can be changed anywhere - according to their visibility (public, private, internal, etc.). for example, a private static field can be changed by all instances of the class.
If a variable is static, it is not a member variable, because it does not belong to a specific instance. Better call them static variables (and not static member variables)
If the Static Member Variable is not Readonly, Variable will be altered at the time of assigning the value to the variable. And it will stay during the life cycle of the application, unchanged.
Also you don't need any instance to assign a value to the variable
Static can be changed anywhere, it is essentially a global variable that you don't need to instantiate.
You should be very careful about using them because they can cause you many headaches and should only be used for specific reasons.
What is the use of static variable in C#? When to use it? Why can't I declare the static variable inside method?
Static variables can edit any where with respect to access permission. Its like non-static variable only. but having common memory(class level memory)
If you are a beginner i will give an example
class Person
{
static int NumberOfPersons;
string name;
int age;
}
In this above example individual memory is required for each person.
But NumberOfPersons case is different. When new person comes you will be simply adding 1 to NumberOfPersons. If you are not keeping a common class level variable for this you will have lots of head ache like you need to go to each object increment one, memory waste etc.
But in case of Name and Age individual memories are required. One persons name shouldn't over written by another object. So that is non-static
In theory- Static will be having common memory and loads while class loads. Non-static will allot memory when object creates
Hopes clear
Thanks & Regards
Binesh Nambiar C
Apparently you can change the this value from anywhere in your struct (but not in classes):
struct Point
{
public Point(int x, int y)
{
this = new Point();
X = x; Y = y;
}
int X; int Y;
}
I've neither seen this before nor ever needed it. Why would one ever want to do that? Eric Lippert reminds us that a feature must be justified to be implemented. What great use case could justify this? Are there any scenarios where this is invaluable? I couldn't find any documentation on it1.
Also, for calling constructors there is already a better known alternative syntax, so this feature is sometimes redundant:
public Point(int x, int y)
: this()
{
X = x; Y = y;
}
I found this feature in an example in Jeffrey Richter's CLR via C# 4th edition.
1) Apparently it is in the C# specification.
Good question!
Value types are, by definition, copied by value. If this was not actually an alias to a storage location then the constructor would be initializing a copy rather than initializing the variable you intend to initialize. Which would make the constructor rather less useful! And similarly for methods; yes, mutable structs are evil but if you are going to make a mutable struct then again, this has to be the variable that is being mutated, not a copy of its value.
The behaviour you are describing is a logical consequence of that design decision: since this aliases a variable, you can assign to it, same as you can assign to any other variable.
It is somewhat odd to assign directly to this like that, rather than assigning to its fields. It is even more odd to assign directly to this and then overwrite 100% of that assignment!
An alternative design which would avoid making this an alias to the receiver's storage would be to allocate this off the short-term storage pool, initialize it in the ctor, and then return it by value. The down side of that approach is that it makes copy elision optimizations pretty much impossible, and it makes ctors and methods weirdly inconsistent.
Also, I couldn't find any documentation on it.
Did you try looking in the C# spec? Because I can find documentation on it (7.6.7):
When this is used in a primary-expression within an instance constructor of a struct, it is classified as a variable. The type of the variable is the instance type (§10.3.1) of the struct within which the usage occurs, and the variable represents the struct being constructed. The this variable of an instance constructor of a struct behaves exactly the same as an out parameter of the struct type—in particular, this means that the variable must be definitely assigned in every execution path of the instance constructor.
When this is used in a primary-expression within an instance method or instance accessor of a struct, it is classified as a variable. The type of the variable is the instance type (§10.3.1) of the struct within which the usage occurs.
If the method or accessor is not an iterator (§10.14), the this variable represents the struct for which the method or accessor was invoked, and behaves exactly the same as a ref parameter of the struct type.
If the method or accessor is an iterator, the this variable represents a copy of the struct for which the method or accessor was invoked, and behaves exactly the same as a value parameter of the struct type.
As to a use case for it, I can't immediately think of many - about the only thing I've got is if the values you want to assign in the constructor are expensive to compute, and you've got a cached value you want to copy into this, it might be convenient.
A storage location of value type in an aggregation of storage locations comprising that type's public and private fields. Passing a value type an an ordinary (value) parameter will physically and semantically pass the contents of all its fields. Passing a value type as a ref parameter is semantically pass the contents of all its fields, though a single "byref" is used to pass all of them.
Calling a method on a struct is equivalent to passing the struct (and thus all its fields) as a ref parameter, except for one wrinkle: normally, neither C# nor vb.net will allow a read-only value to be passed as a ref parameter. Both, however, will allow struct methods to be invoked on read-only values or temporary values. They do this by making a copy of all the struct (and thus all of its fields), and then passing that copy as a ref parameter.
Because of this behavior, some people call mutable structs "evil", but the only thing that's evil is the fact that neither C# or vb.net defines any attribute to indicate whether a struct member or property should be invokable on things that can't be directly passed by ref.
I am initializing a mutable class instance as a local variable with new keyword. Then I pass this object as a parameteter to a delegate. Is this variable's lifetime extended by the delegate? Do other threads use this variable or create their own instances? I may be asking the obvious but I want to be sure.
public void DoSometing(Action<Foo> action)
{
Foo foo = new Foo();
action.Invoke(foo);
}
Whenever you pass local variables that "escape" the method one way or another, you do extend its lifetime. In C# you will never operate upon a variable that contains a reference to a non-existant object -- the concept makes no sense in a managed environment.
So yes, foo will continue to live on, and you will need to be concerned with thread-safety in exactly the same way as if you simply called another ordinary method. In this scenario, lambdas do not change the complexion of the problem.
However, sometimes this can be more subtle, especially if you return a lambda -- one which closes over local variables. In such a scenario, all the variables you reference from within the lambda live on in the same way as foo.
In my program i am passing a locally constructed variable to a global class object's member function. The member function will assign this variable to a private member and use it through out the program. Is there any drawback in this approach?
public void function()
{
int a = 0;
globalClassObject.StoreValue(a);
}
This is fine. The problem would be if you would pass a reference to this variable. In this case the value is "copied" to the variable within the function so the original a variable isn't actually used.
I don't see a problem with this. The variable is used in local scope only, so no unexpected results here.
The big drawback is if this value can be changed anywhere else in the program. If it can, your program will become a swamp for bugs to breed. If the globalClassObject stores the value immutably, there is no problem.