This question already has answers here:
Cannot use 'this' in member initializer?
(3 answers)
Closed 7 years ago.
Why does the compiler give an error about this being unavailable that when initializing an instance variable when defining it?
Keyword 'this' is not available in the current context
The constructor initialization is fine. I understand the scenario here - I just wanted to find the reason (via MSDN or otherwise) why "this" is available to a constructor but not directly if initializing the member variable.
Here is a simple abstraction of the error I'm seeing.
public class ClassA
{
// Gets compiler error that "this" unavailable
protected ClassB _a1 = new ClassB(this);
// Works fine
protected ClassB _a2;
public ClassA() { _a2 = new ClassB(this); }
}
public class ClassB
{
public ClassA A { get; private set; }
public ClassB(ClassA a) { this.A = a; }
}
I was hoping to keep my initialization next to the assignment since the above example is an abstraction of my code where I am defining Lazy valueFactory delegates for 10-15 member variables in which the delegates need the data context passed as a parameter to the constructor. With 15 member variables, I'd prefer to keep the assignment next to the definition on a single line instead of having 15 lines of definitions and then another 15 lines in the constructor initializing each one.
This is basically what I had to do in my actual code:
public class MyContext
{
public ProgramService Programs { get { return _programs.Value; } }
protected Lazy<ProgramService> _programs;
public MyContext()
{
_programs = new Lazy<ProgramService>(() => new ProgramService(this));
}
}
Basically to keep you from relying on the order (textual) and possibly non-usable state of the class under construction. I think the overriding principle at stake is that if it's "complicated" logic, then you should be using a constructor.
Eg., doing this:
class A {
private int x = 1;
private int y = this.x + 1;
}
would lead to different results than:
class A {
private int y = this.x + 1;
private int x = 1;
}
which is a little unexpected. To side-step the issue, but still allow the convenience of inline init - disallowing this makes the ordering not matter.
In your actual code, you could possibly do a lazy check to keep things located together:
public ProgramService Programs {
get {
if (_programs == null) _programs = new ProgramService(this);
return _programs.Value;
}
}
// change this to private to keep subclasses from accessing a possibly null reference
private Lazy<ProgramService> _programs;
Related
This question already has answers here:
Why doesn't C# support local static variables like C does? [closed]
(13 answers)
Closed 3 years ago.
I came to know that,
From MSDN:
C# does not support static local variables (variables that are declared in method scope).
And here:
The static modifier can be used with classes, fields, methods, properties, operators, events, and constructors, but it cannot be used with indexers, destructors, or types other than classes.
That is, local variables are not allowed as static inside a method.
Therefore, the below code will not compile
public class Base1
{
public int getHighscoreString()
{
int highscore = Int32.MinValue;
static int max = 10; // It is not allowed here.
if(max>highscore)
highscore = max;
return highscore;
}
}
But, we can always do the same functionality by
public class Base1
{
static int max = 10;
public int getHighscoreString()
{
int highscore = Int32.MinValue;
if(max>highscore)
highscore = max;
return highscore;
}
}
So, is it a design decision that static variable can not be used as local variable inside a method or any reason behind it?
A static variable is a variable that lives beyond the instances of the class in which is declared, in the sense that to get or set its value you have to call its class type and not its instances. This happens because a reference to the memory address where the static variable lives is kept regardless of the construction or disposal of instances of that class. Say you have a Zoo class:
public class Zoo
{
public static int counter;
public string Name;
public void AddAnimal(string name)
{
Name = name;
counter++;
}
}
The counter increases every time you add an animal to the zoo, and you can get the total anytime by calling
Zoo myZoo = new Zoo()
myZoo.AddAnimal(“tiger”);
Zoo.counter; // 1
myZoo.counter // wrong!
Apart from myZoo.counter being wrong, the main thing to notice is that even if we dispose of the myZoo instance, the counter field will always keep the total of the animals in the zoo!
On the contrary, variables declared in a method are immediately disposed after method execution and therefore you cannot reference them outside of that method because the memory address where the variable “lived” is not available anymore.
I hope this clarifies the matter a little more. Cheers!
Is there a .net method that determines whether or not a given method has been previously called for a given object instance?
Sometimes a property getter method has side effects. For instance, a property getter if not called previously may need to create additional objects and perform other work in order to return the value of a backing field. I can't have that happen. If the getter method hasn't been called previously, I don't need the value.
For example...
object item = something;
foreach (PropertyInfo propertyInfoForItem in item.GetProperties(Reflection.BindingFlags.Public)) {
//Need something to avoid calling this if the property getter method has not been previously been called for this item
object itemPropertyValue = nothing;
itemPropertyValue = propertyInfoForItem.GetValue(item, null);
}
I've looked through the MethodInfo class returned from PropertyInfo.GetGetMethod() and didn't spot anything there that would help.
Any ideas?
As an additional note based on feedback (and thanks for chiming in!), I wouldn't be able to modify the existing objects I'm inspecting.
I think your way of achieving this goal is overly complicated. You can simply use a bool or numeric class-level variable for this purpose.
public class C
{
private int _counter = 0;
// private bool _methodCalled = false;
public void M()
{
// check the state of _counter or _methodCalled
_counter++;
// _methodCalled = true;
}
}
You can make the private variable static if you want to take all calls into account, regardless of the instance of the class that was used to invoke it.
Note that locking may be necessary if there is some multi-threading going on and you have conditional branching depending on the counter.
EDIT
Since the class cannot be modified (as stated in the comment), you'll need to create a wrapper class that will aggregate your class and hold the counter.
public class CWrapper
{
private int _counter = 0;
private C _c = new C();
public M()
{
if (_counter == 0)
{
_c.M();
}
counter++;
}
}
Since you've stated a few times that you do not have the ability to modify the objects in question, your only option is going to be to implement wrapper classes for those object types. In your wrapper class you can expose all of the properties and methods on the objects in question, but you can implement in your wrapper Getters the reference counting suggested in the other answers.
If you need to determine if a Getter has been called before you have access to the object, I'm afraid you are out of luck.
You could make a static count within the class and then within the method for the first time increment to 1 if 0 and subsequent times if 1 then you know it has been called already and you can return -1 or whatever.
You can use the decorator design pattern in order to do it.
class Program
{
static void Main(string[] args) {
var hasDoMethodInstance = new HasDoMethodImpl();
var hasDoMethodDecoratorInstance = new HasDoMethodDecorator(hasDoMethodInstance);
hasDoMethodDecoratorInstance.Do();
}
}
public interface IHasDoMethod
{
void Do();
}
public class HasDoMethodDecorator : IHasDoMethod
{
private int counter = 0;
private readonly IHasDoMethod hasDoMethod;
public HasDoMethodDecorator(IHasDoMethod hasDoMethod) {
this.hasDoMethod = hasDoMethod;
}
public void Do() {
hasDoMethod.Do();
counter++;
}
}
public class HasDoMethodImpl : IHasDoMethod
{
public void Do() {
//Your logic
}
}
Consider the code below. Fields i and j are initialized before m and n. We know that the parent object is created before the child object, but in my program the compiler is allocating and initializing memory for the child class' member variables before the base class'. Why is that?
class X
{
private int m = 0;
private int n = 90;
public X() { }
}
class Y:X
{
private int i = 8;
private int j = 6;
public Y()
{ }
public static void Main(string []args)
{
Y y1 = new Y();
}
}
This is explained in Eric Lippert's blog:
[...] an initialized readonly field is always observed in its initialized state, and we cannot make that guarantee unless we run all the initializers first, and then all of the constructor bodies.
Not sure why readonly is mentioned here, but for example, this ensures that the following scenarios, albeit being stupid, work:
1.
class Base
{
public Base()
{
if (this is Derived) (this as Derived).Go();
}
}
class Derived : Base
{
X x = new X();
public void Go()
{
x.DoSomething(); // !
}
}
2.
class Base
{
public Base()
{
Go();
}
public virtual Go() {}
}
class Derived : Base
{
X x = new X();
public override void Go()
{
x.DoSomething(); // !
}
}
This order is explicitly stated in C# Language Specification (17.10.2):
[...] constructor implicitly performs the initializations specified by the variable-initializers of the instance fields declared in its class. This corresponds to a sequence of assignments that are executed immediately upon entry to the constructor and before the implicit invocation of the direct base class constructor.
This is one of those rare places where an understanding of procedural methodology makes object-oriented methodology easier to understand. Even though you're working OOP, the compiler still adheres to procedural logic - working start to finish.
A simple example is when the compiler hits private int n = 90. First it allocates space for an integer value, then an identifier to access it as an integer, then assigns it the value of 90. It can't assign the value until it both has the space to stick it AND knows how to access it, nor can it access non-existent space.
In this instance, your derived class Y is built atop the base class X, similar to how the variable n is built atop the "class" integer in the example above. This is triggered by the declaration class Y:X - the compiler can't even start building Y until it understands how to build X.
Child construction code must be allowed to call functions on the parent, which can't work unless the parent is already fully-constructed.
However, the objects share the same memory block. So all the memory is allocated in one go, then the classes are initialized working up the class hierarchy.
I am new to C# programming.
Please help me.
I created a class Tester:
class Tester
{
public int a = 5;
public int b = a;
}
Question 1 : Why am I not able to use this variable a for initializing the variable b.
Question 2: If I changed the variables to static then it works fine. Why is there a difference?
class Tester
{
public static int a = 5;
public static int b = a;
}
Question 3 : In previous example if I swap the sequence of variable then it works fine why because a is declaring after b . How can it initialize a?
class Tester
{
public static int b = a; // 0
public static int a = 5; // 5
}
There are some icky initialization order issues when you use fields initializers. A simple example would be:
class Test {
int a = b;
int b;
public Test() {
b = 1;
}
}
What will be the value of a? If you use the constructor-initializes-object rule then a will be 1. That however not the way it works under the hood, a would be 0 if the syntax where valid. A side-effect of the way field initializers are implemented, their code is injected into the constructor before the code in the body of the constructor. This problem gets a lot more convoluted when the class inherits base classes that have constructors.
This is too ugly, the C# language designers solved this by simply forbidding this kind of code. The rule is that you cannot reference this in a field initializer, that will create a reference to an object whose class constructor hasn't finished executing.
The rule is relaxed for static fields, there is no this reference and the CLR provides decent guarantees for class initializer execution order. That however doesn't avoid ambiguity, it is an exercise to guess what the field values will be in this example:
class Test {
static int a = b + 1;
static int b = a + 1;
}
Try it and see if you can make sense of the result. It is otherwise well-defined.
Answer1: You cannot use an instance variable to initialize another instance variable. Why? Because the compiler can rearrange these - there is no guarantee that variable "a" will be initialized before "b", so the above line might throw a NullReferenceException.
Answer2: It works fine with static because static are initialize before other variables and their references are not changed.
Please let me know if it helps.
As Anirudh said. You cannot use an instance variable to initialize another instance variable. Why? Because the compiler can rearrange these - there is no guarantee that a will be initialized before b.
You can use constructor for this.
class Tester
{
public int a=5;
public int b;
public Tester()//constructor
{
b=a;
}
}
or
class Tester
{
public static int a = 5;
public static int b;
public Tester()//constructor
{
b = a;
}
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I sometimes need to go online and find a tutorial for something. I am often finding that some people put code like this:
this.button1.Text = "Random Text";
Then I find code that is just like this:
button1.Text = "Random Text";
Is it better to use the this.whatever or does it not matter?
It depends. Here's an example class:
class A
{
private int count;
public A(int count)
{
this.count = count;
}
}
In this case, the "this." is mandatory because it disambiguates the reference on the left of the assignment. Without it, it is not clear to you reading the code whether "count" would refer to the parameter or the field. (It is clear to the compiler, which has rules to follow.) But in most cases, it is purely a matter of preference.
Write all your code to emphasize salient points to the reader. If you feel that it is important for the reader to clearly understand that an identifier refers to an instance member then use this. If you feel that its an unimportant and distracting implementation detail, don't. Use good judgment to make your code readable.
this is just to make it clear, in some cases we have to use this:
Differentiate between parameter and local member:
//local member
object item;
private void SomeMethod(object item){
this.item = item;//must use this
}
Pass the current class instance into another method:
public class SomeClass {
private void SomeMethod(SomeClass obj){
//....
}
private void AnotherMethod(){
SomeMethod(this);//pass the current instance into SomeMethod
//.....
}
}
Use in extension methods:
public static class SomeClassExtension {
public static void SomeClassMethod(this SomeClass obj){
//use obj as a reference to the object calling this method...
}
}
Call a constructor from another constructor (with different signature):
public Form1(string s) : this() {//Call the Form1() before executing other code in Form1(string s)
//......
}
Use for declaring indexers:
public class SomeClass {
//declare an index returning a string
public string this[int index] {
get {return ...}
set { ... }
}
}
Use auto-properties in struct:
public struct SomeStruct {
public object AutoProp1 {get;set;}
public object AutoProp2 {get;set;}
public SomeStruct() : this() //must use this
{
AutoProp1 = someObject;
AutoProp2 = someObject;
}
}
Cast the current instance to the based classes/types:
public class ClassB : ClassC {
//...
}
public class ClassA : ClassB {
public ClassA(){
((ClassC)this).MemberOfClassC ... ;//There might be some member in ClassC
//which is overridden in ClassA or ClassB, casting to ClassC can help we invoke the original member instead of the overridden one.
}
}
There might be some other uses of this, however I'll update later if I think out.
It does not matter, it is a matter of style. I tend to omit this, since it is just extra code to mentally parse.
The only case it matters is when there is a naming conflict between local and instance variables, in which case this can be used to disambiguate between a field and a local variable.
Here is an example of the type of situation where it does matter:
public class Foo
{
private string x;
public Foo(string x)
{
// x = x; Assigns local parameter x to x, not what we want
this.x = x; // Assigns instance variable x to local parameter x: this disambiguates between the two.
}
}
an example of using this can be to access class variable when you already have a similar variable in the scope. Otherwise it is mostly of choice.
Example
public class Test
{
public string firstName { get; set; }
public void temp(string firstName)
{
firstName = this.firstName;
}
}
In regards to fields the only case where this is explicitly needed is when there is a naming conflict:
public class Foo
{
private string bar;
public Foo(string bar)
{
this.bar = bar;
}
}
So some will prepend an underscore:
public class Foo
{
private string _bar;
public Foo(string bar)
{
_bar = bar;
}
}
Usually it will not matter. This reason why you might use this. is to explicit say that you want to reference a property/field that belong to the current class.
Again, there are not many occasions when you are likely to need this, but for example you might have a local variable with the same name as a class level property/field. Then you could use this..
For example:
class MyClass
{
string s = "1";
void MyFunction(string s)
{
//s = local value as passed in to function
//this.s = "1"
}
}
It doesn't usually matter. The this keyword "refers to the current instance of the class and is also used as a modifier of the first parameter of an extension method."
Check out this article.
http://msdn.microsoft.com/en-us/library/dk1507sz.aspx
generally it doesn't matter, but if you pass in a variable called, say button1, to a class method that already has a member called button1, then you'll need to disambiguate which one you really meant.
This is probably why people now use this. to explicitly say which variable you meant, if you use this practice all the time, you'll not get it wrong in the few cases where its important.
Of course, you could ensure that all member variables are uniquely named, say with a prefix like m_, but that's fallen out of fashion nowadays, people prefer to write out this.
It really depends on the situation.
http://msdn.microsoft.com/en-us/library/dk1507sz(v=vs.80).aspx
To qualify members hidden by similar names
To pass an object as a parameter to other methods
To declare indexers
As others have already pointed out, it is useful in distinguishing field/property with method variables, One other place where this is required is to invoke Extension methods on current instance. For example this.ExtensionMethod(); would work, but not just ExtensionMethod();
Other than that, its a matter of personal choice, some call it redundant and some like to use it. It totally depends on you and your team.
Personally I like to use this with class members, specially for Forms method if working on code-behind of winform, like this.Close();
For more discussion when to use this see: When do you use the "this" keyword?