I want change the text of a label on one form to the text of a button on another form when I press the button.
To do this I have created this on the form where the label is
public static void changeText(string text)
{
L1.text = text;
}
this code is on the form with the button
mainForm.changeText(this.Text);
It then gives the error : An object reference is required for the non-static field, method, or property...
This may seem like a stupid question but I am still new to C# so please help me.
About static and non-static members
There are two kinds of type members: non-static and static. Non-static members are also called instance members, because they appear in the object instances of the type. Static members are bound to the type itself, and not its object instances, so you can use them without actually instantiating the type.
Consider the following:
class MyClass
{
// static member: can NOT reference 'this', as it is not in the context of an object instance of the type
public static bool IsTrue()
{
return true;
}
// constructor: this runs whenever the type is instantiated
public MyClass()
{
}
// instance member: can access to 'this', which references the context object instance of the type
public int GetNumber()
{
return 42;
}
}
You can use the above type as following:
if(MyClass.IsTrue()) // static call
{
var myObject = new MyClass(); // constructor call
int result = myObject.GetNumber(); // instance member call
Console.WriteLine(result);
}
On to your specific problem...
If you're perfectly sure that you need that logic inside a static method, you'll need to get an object instance of the form you wish to change.
Unfortunately singletons don't work very well, because the VS designer needs to create an object instance of your Form, which obviously violates the singleton pattern.
What you can still use, is (in case of a Windows Forms application): Application.OpenForms. This returns a read-only collection that contains all currently open forms of the application. You can use this to find the object instance of the form you want to change, and then perform that change.
Be advised that if this is a multi-threaded situation (i.e. the static method runs in a different thread than the GUI thread), you'll have to use some sort of synchronization mechanism, such as InvokeRequired and Invoke().
L1 is not static, so you cant have a static function interacting with it. Having a static let you able to write something like MainForm.changeText(...), but in this case what is L1 ?
I think we can say:
You dont need a function to change the label text, the property Text is already written
If there is some logic needed to mangle the tet before you can:
Consider if the function you need is so general that can apply to many labels across your app, in this case an extension method would be good. In other case if you want a function in the main form to set the text somewhere, and this place can change, or the text need some mangling, a member function would be good, and probably a DataBinding would be better.
You don't want to use a static method for this since L1 is a member of the mainForm class.
The error means your static function is accessing a non-static variable (control L1).
Static functions can only access to static variables. You can change L1 to static variable to make it work.
Related
I've read the other threads on the subject but I'm having no joy.
I'm trying to update the content of my wpf TextBlock from inside a static method UpdateTextBlock, this method needs to be static as I'm calling it from inside a Timer and it'll only work for some reason if it is static.
public static void UpdateTextBlock()
{
foreach (String s in GetWhoList())
{
TextBlock1.Inlines.Add(s);
}
}
Basically need to find a way to reference TextBlock1 to the object that it appears in I think. Struggling to get my head around the methodology of it. I understand that it doesnt know what to reference because it's static, but not sure the commands to tie it to the TextBlock in my Windows App.
I'm generating error code CS0120
An object reference is required for the non-static field, method, or property 'MainWindow.TextBlock1'
Create a static property that contains TextBlock1's control. TextBlock1's window can initialize it, for example, in the "loaded" event or anywhere else you think is right.
Consider removing static modifier from the method that works with non-static objects instead.
I'm coming from an obj-c background looking at some C# code. In a partial subclass of Window, I see this at the top of the code:
public partial class MyMessage : Window
{
private static object _messageLock = new object();
private static MyMessage _f = new MyMessage();
What are these types of member variables used for? I know you can create a static variable for a class so that it is used for the whole class (the classic example being some int count variable that will increment every time the class is instantiated in order to keep track of how many objects of that class are instantiated). In this case, I am not sure what it means.
Thanks.
private static object _messageLock = new object();
private static MyMessage _f = new MyMessage();
This looks like the class creates a Singleton of type MyMessage and then controls access to it using a lock on the messageLock variable - hard to verify though without the full code.
Well i can answer what the first member is used for. This is for creating a thread lock. One object which is used to mark which thread currently holds the lock and can do his business. I guess the second member is used for threading aswell, but without the rest of the code its difficult to answer.
So these two members are privat static which means only one instance of these variables no matter how many MyMessage objects are created and can only be accessed inside MyMessage instances.
These static member variables store things that are scoped to be available to every object created from that class - so one variable shared amongst 0 to many objects. These are private, so they are only available to code from within the class.
The _messageLock looks like its probably intended to be an object used in a lock() statement, somewhere in the class there is probably:
lock(_messageLock)
{
// some code
}
Or somethign using some other form of thread-safe lock. This is intended to create some form of 'one thread only' portions of the code.
Combined witht the static MyMessage - I'm guessing this is a form of singleton. There are a number of different C# singleton patterns discussed in this MSDN article
I think what you are asking is simply 'What is a static field', not 'What are the specific private static fields doing here' like everyone else seems to be answering.
A private static member variable such as the ones in your example are private member variables that can be accessed by ANY object of that class. Any instance you create of MyMessage will be able to access those member variables.
It seems that MyMessage is a singleton class, and it internally manages a private variable called _f which is actually the singleton instance.
And from the name, it guess that _messageLock is used in lock statement, to protect critical code section, (such as in multithreaded application), as:
lock(_messageLock)
{
//critical section
}
Have a look at : lock Statement (C# Reference) at MSDN
In C#, a common pattern that I use is to populate the details of a lower calculation class with a form object.
The constructor for MyForm is:
MyForm()
{
_MyFormCalcs = new MyFormCalcs(this);
}
But I encountered an error today which makes me think that as my constructor had not finished completing, it creates a new instance of MyForm to pass into MyData. Thus it calls the constructor twice. I found that a static list in MyFormCalcs was being filled twice and was failing the second time as the keys were already present in the list.
Can I use this in the constructor to refer to this instance? What will it contain in the lower class - has the constructor been run or not.
What is a better way of passing my form into the lower class?
No, that won't create a new instance of MyForm.
In general, allowing this to "escape" from a constructor is dangerous as it means it can be used before the constructor has completed, but it's not going to be creating a new instance. If you could give a short but complete example of the problem you've seen, we could help diagnose it further. In particular, it's not clear what you mean about the "static list being filled twice". Usually it's not a good idea to populate a static variable in an instance constructor.
In fact, it is really nice to avoid such call inside constructor, because your object is not already built (constructor hasnt finish its work) but you are already use this "unfinished" object as a parameter. Its a bad way. Good way is creating some special method:
class MyClass
{
var obj:SomeClass;
public MyClass()
{
}
public Init()
{
obj = SomeClass(this);
}
}
Make a private property that instantiate MyFormCalcs only when it is first used, like this:
public class MyForm {
private MyFormCalcs MyFormCalcs {
get {
_MyFormCalcs = _MyFormCalcs ?? new MyFormCalcs(this);
}
}
}
This way, you don't have to think about when to "initialize" things.
There is this very complete response of C# constructor order:
C# constructor execution order
Hey! I've made a little boiler system that's controlled entirely by a form. The form components, however, call functions in a class for the boiler, radiators and so on.
I've got a little main class to that instantiates all of the classes but I'm struggling to figure out how to pass the form object to those classes so that they can access the form's components.
I guess I should be using mutator methods in each class to store the form object? How would I do this that's syntactically correct?
Thank you! ;o)
Just pass the form to each class. Store it in a private variable so the class can use it later. It is passed by reference by default.
class Boiler {
private Form parentForm;
public Boiler(Form f) {
parentForm = f;
}
}
When you pass a reference type to a method, C# (by default) will pass a copy of the reference to the method. This means that if pass the reference you have to your classes you are giving the method a copy of that reference and since both copies reference the same object both the call site and the method will have access to the same instance.
For example:
class Example
{
static void Main()
{
string s = "hello, world";
// Here we are passing a copy of the reference
// stored in "s" to "Print"
Print(s);
}
static void Print(string str)
{
// By default, "str" will be assigned the copy of the
// reference passed to this method.
Console.WriteLine(s);
}
}
I would be careful building an application in which your domain objects (in your case, Boiler, Radiator, etc.) know about the UI layer that consumes them. If you find that you need to pass a Form to one of these domain models you are probably doing something wrong. If you show us a small example of what you are trying to accomplish we might be able to help you come up with a more maintainable solution.
Why can't the keyword this be used in a static method? I am wondering why C# defines this constraint. What benefits can be gained by this constraint?
[Update]:
Actually, this is a question I got in an interview.
I do know the usage of 'static' and 'this', based on all your response, I guess I know a little of why the two can not be used together. That is, for static method is used to changed state or do something in a type level, but when you need to use 'this' means you want to change the state or do something in a instance level. In order to differentiate the state change of a type and the state change of an instance, then c# donot allow use 'this' in a static method. Am I right?
Because this points to an instance of the class, in the static method you don't have an instance.
The this keyword refers to the current instance of the class. Static member functions do not have a this pointer
You'll notice the definition of a static member is
Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object
Which is why this has nothing to point to.
this is an instance of the current object. With a static method, there is no current object, and as such, this doesn't exist. It's not really a constraint, but the entire point of a method being static.
this refers to the current instance of a class and can therefore be used only in instance methods. Static methods act on class level, where there are no instances. Hence, no this.
this refers to the current instance of the object. A static method is a method on the class. It is not an instance method and therefore using this inside a static method is meaningless.
I'm pretty sure this isn't limited to C# and it isn't a constraint, it's a logical situation. As #Yuriy correctly states, this refers to the current instance of a class, i.e. you've used new (or DI) to instantiate the class (created an instance of) and you need some way internally to refer to that instance, i.e. this object. A static method is called without instantiating the class, there is, in effect, no object created and as such you can't access properties of which this is one.
By static methods you can write:
MyClass.static_method();
which there is nothing to do with any object instance (so you don't need this keyword).
Because static_method() works and doesn't need object instances for its job. static_method() doesn't know which object instance do you have, but it can change the behavior
of all object instances:
MyClass a = new MyClass();
MyClass b = new MyClass();
MyClass.static_method("PRINTER");
a.display(); //print something
b.display(); //print something
MyClass.static_method("MONITOR");
a.display(); //display something on monitor
b.display(); //display something on monitor
In this case, static_method() changes the behavior of display() method in all object instances of MyClass.
The keyword this refers to the instance of the object. In the static context there is not specific instance to reference.
The this keyword can be used in a method marked as static. The syntax is used to define extension methods in C#. This feature has been available since C# 3.0, released in 2007 (Wikipedia)
In the normal usage, this refers to the instance, static says that there is no instance (and therefore no this). The fact that you can't use them together (aside from special exceptions like extension methods) follows naturally from understanding what this and static are, conceptually.
this is used to refer to the parent object of a variable or method. When you declare static on a method the method can be called without needing to instantiate an object of the class. Therefore the this keyword is not allowed because your static method is not associated with any objects.
'this' refers to an instance of a class. Static is initialized without instantiation and hence the static method cannot refer to an 'instance' that is not created.
The short answer for you will be: this refers to an instance of a class which is non existing in a static scope.
But please, look for a good book/class and try to understand basic object oriented concepts before going further on any object oriented programming language.
I am not sure if this helps your problem, but I believe these two code snippets are equivalent:
MyStaticClass.foo();
and simply
foo();
will both call the foo() method in the MyStaticClass class, assuming you call foo() from inside MyStaticClass
Edit - The easiest way to remember the difference between a static class and a non-static class is to think of something like the Math class in java. You can call Math.abs(x); to get the absolute value of x, and it does not really make sense to instantiate a Math object, which is why Math is a static class.
Another, more literal, take on your question:
The 'this' keyword can't be used in a static method to avoid confusion with its usage in instance methods where it is the symbol to access the pointer (reference) to the instance passed automatically as a hidden parameter to the method.
If not by that you could possibly define a local variable called 'this' in your static method, but that would be unrelated to the 'this' keyword referenced instance in the instance methods.
Below is an example with two equivalent methods, one static the other an instance method.
Both method calls will pass a single parameter to the methods executing code that will do the same thing (print the object's string representation on the console) and return.
public class Someclass {
void SomeInstanceMethod()
{ System.Console.WriteLine(this.ToString()); }
void static SomeStaticMethod(Someclass _this)
{ System.Console.WriteLine(_this.ToString()); }
public void static Main()
{
Someclass instance = new Someclass();
instance.SomeInstanceMethod();
SomeStaticMethod(instance);
}
}