how to declare a variable to be used in several methods? - c#

I am fairly new to C# programming (and programming in general). I want to use a variable in two different methods I thought I needed to declare the variable just inside the class but I keep getting this error message "Error: A field initializer cannot reference the non-static field, method, or property" I am sure it is a relatively simple error on my part, but how do I fix this?
After researching online for awhile I think I am on the right track of understanding classes but my understanding is obviously lacking.`
public partial class MainPage : ContentPage
{
public string path = diceNumber.SelectedItem.ToString();
public MainPage()
{
InitializeComponent();
}
private void DiceRollResult_Clicked(object sender, EventArgs e)
{
if (path == "One")
{
DisplayAlert("One", "You Lost", "Close");
}
else if (path=="Two")
{
DisplayAlert("Two", "You Lost", "Close");
}
else if (path == "Three")
{
DisplayAlert("Three", "You Won", "Close");
}
// The else if statements are just to show you how I am using the code.

A few things for you to understand here:
If you assign a value to a class-level variable, it is executed before any other part of the class. So diceNumber.SelectedItem won't even exist at the time when path is being initialized. That is the cause of your error. You can only use static fields or values to assign to a class-level variable for initialization (because static members do not need an instance).
Then there is a logical mistake you're making. Even if it were possible to assign diceNumber.SelectedItem to your variable upon startup, you probably don't want to do that, because then it would only be executed once upon startup. What you actually want it to do is to check currently selected value at the time of click and then respond accordingly. Therefore you should move your path variable inside the click handler because I don't see you're using it anywhere else.
Lastly, if you need to access this value in other functions too, you can create local variables inside those functions just like this:
string path = diceNumber.SelectedItem.ToString();
in all the functions where you need this. No need of a global variable.
In essence, diceNumber (which is probably a UI control) itself is a global class-level variable. So it will do everything that your path variable is doing for you. Not sure if this is WinForms or WPF or something else, but you can always see the declaration of these UI controls as class-level variables in the code-behind.

This seems to be a Xamarin.Forms application, its not a good practice to use a variable in several methods you would generally use a class and instantiate that class throughout the lifespan of your program.

You can access a variable from any other class or form by making it a static variable.
public static string path = diceNumber.SelectedItem.ToString();
Now in any class or in any method, you can access the variable by
var s = MainPage.path;
The static member is always accessed by the class name, not the instance name. Only one copy of a static member exists, regardless of how many instances of the class are created. Static methods and properties cannot access non-static fields and events in their containing type, and they cannot access an instance variable of an object unless it is explicitly passed in a method parameter.

Related

Calling variable from other class by inserting its name as variable

My problem is this, I wanted to have a bunch of variables which I called GlobalVariables that I can use and change on demand. I used dictionary for that which was rather usefull however 2 problems arose. First that I can use only one type and second is that later I wanted to use those variables in multiple class.
My next solution was to use separate class to define variables there and use them like GlobalStatus.Variable. Seemed like a good idea however now I am faced with the problem that I need to call my GlobalStatus variables by other variable. I can't put it into words(thats the reason why I am asking this question) but here is how it was done with Dictionary.
foreach (string String in Array) {
if (GlobalStatus[String] == "Test") {
...
}
}
Can I emulate this behavour using Class to store variables, or I should use another way to store said variables?
As David pointed out you probably wanna avoid global variables unless you have a good reason to have them.
That said, if I were you I'd probably make something like
namespace Global{
public class Options{
public static Options _Instance;
void Awake(){
if (_Instance == null)
{
_Instance = this;
}
}
}
}
Then you may call this global Options class from anywhere using the Singleton _Instance variable by saying Global.Options._Instance.*Your variable or method*
This way you can have a namespace called Global which can hold your global variables in an orderly fashion.
I advise you to divide your variables into classes instead of having a dictionary to hold it all, unless there is good reason to.
The task is:
We have an array of 2 strings: name and value. This is called requirement. Requirements are kept in global class as static variables. How to compare requirement in the class with a requirement parameter like new array string[2].
After some discussion one of possible solutions
Use array of requirements in global class
Use requirement name as integer instead of string type.
Then requirement name can be used as index of global array.

Call object in another class in another file with Visual Studio

I have a public class A in a file called A.designer.cs and there is a textbox object called Textbox1 in there that I want to use. It is declared as:
public DevExpress.XtraGrid.Views.Grid.GridView textbox1
I want to use it in my b.cs file, which is of a public partial class b. How do I call the Textbox1 in class A?
I tried
A.Grid.GridView.textbox1.Text = "hi"
but it is giving me the error that the file
"does not contain a definition for "grid"".
It's a public instance member of class A so you need an instance A and you can then access its textbox1 field. You've already done this same thing a hundred times before with various other members of various other types. Why try to make it harder this time?
the scenario doesn't make much sense to me but if that's the case.. Do it as usual.
//get a instance of A, something like
A a = new A();
//access by:
a.textbox1
But really you may want to think about why accessing a gridview from outside.

Interaction between two separate Windows in wpf

How can I access a variable in MainWindow.xaml.cs that is defined as public from Window1.xaml.cs?
I thought that if a variable is defined that way I will be able to access it from anywhere. What am I missing here?
I thought that if a variable is defined that way I will be able to access it from anywhere
Unless the variable is both public and static, you can't access it from almost anywhere coz that should be accessed based on a certain instance of an object.
If you wanna access a variable from any window, either make it static or call it based on an instance of that window like
Window1 win = new Window1();
win.Variablex = 1;

What is the equivalent of a C/C++ global variable?

I am new to C#. Come from the C/C++ environment. My application has a List<Model> which is required all over the place, by different classes. The problem is that a copy will not do because this statement:
dataGrid.ItemsSource = myModelList;
requires the original by address. I tried changing some arguments around and passing that particular variable as ref but as soon as it is assigned with an equal sign, I end up with a copy. Correct?
You could make it a singleton.
However a concrete List needed all over the place would make me have a serious think about my design.
At the very least you should consider writing a class to control access to the list (add, remove, clear etc), and making that "global", otherwise you are going to be in deep in the brown stuff, until it hits the fan.
Create a Public Class and have the content you wish to pass declared static within the class. Then just access it as NameOfClass.NameOfMethod()
public class NameOfClass
{
public static RETURNTYPE NameOfMethod()
{
// Your Code
}
}
You can create a public class for it with a public static List inside it. That one you then can access everywhere.
eg
public class FakeGlobal
{
public static List<Model> MyModelList = new List<Model>();
}
or even make it a property with getter/setter.

how to declare const which can be initialized at runtime only

My class contains LOT_SIZE constant which can not be changed. But I can initialize it only during execution, because I obtain LOT_SIZE from Securities table at runtime. However I want to make clear that this is constant and I want to protect it from changes from any other places except one "friend" place where I want to initialize it ("Securities" table read).
Do we have something for that in C# or I just have to use LOT_SIZE as regular variable?
I can not declare LOT_SIZE as readonly because during object construction "Securities" table still not read and so I don't know LOT_SIZE value.
The best way is probably to read the value before creating the class that must hold it, so you can pass it into the constructor and put it into a readonly field. But as you've excluded doing it the obvious way...
You could use a read-only property (a property with a get but no set) and always access it via the property except in the place where you initially set up the value.
If you don't even want to risk changing it from within your own class, then create a class to "wrap" the value. This class would do nothing more than read the value when required the first time and expose it as a read-only property to your consumer classes.
But whichever way you choose, please don't use "1970's C macro constant" (ALL_CAPS) naming for your constant :-)
You cannot declare a variable in a way that it can be modified in one place and not in any other (except for readonly which you excluded).
I suggest you use some kind of "lazy pattern". Write a class which wraps a value and allows the value to be set exactly one time. You can make the variable referencing an instance of this class read-only.
class WriteOnce<T>
{
T _val;
bool _isInitialized;
public T Value {
get { if (!_isInitialized) throw; return _val; }
set { if (_isInitialized) throw; _val = value; }
}
}
...
class SomeOtherClass {
readonly WriteOnce<int> LOT_SIZE = new WriteOnce<int>();
}
You could make a class to read from your table with a private member variable (even make the class a Singleton to get uber fancy). Then make a static public variable with only a getter. It's a bit overkill, but that would be the only way to allow it to be set after initialization, but only able to be modified the one time.

Categories