Classes & Constructors: Incrementing a variable outside class - c#

I am currently working with classes and constructors. I have sint variable named current that equals 0 inside the constructor. Now when I click the button I am trying to increment property current and then call GetNextTree to display. But when incrementing current++ from button click I receive this error: does not exist in current context. What would be the proper way to increment current then?
public class fruit_trees
{
}
public class ListForTrees
{
public int current;
public fruit_trees GetNextTree()
{
current = 0;
fruit_trees ft = first_tree;
int i = 0;
while (i != current)
{
ft = ft.next_tree;
i++;
}
return ft;
}
}
private void ShowNextItem_Click(object sender, EventArgs e)
{
//Show Last Item
fruit_trees obj = mainlist.GetNextTree();
if (obj == null)
{
labelSpecificTree.Text = "No more trees!";
}
else
{
//error: current does not exist?
current++
labelSpecificTree.Text = obj.next_tree.GetTreeType.ToString();
}
}

The problem is in the scope (encapsulation) where you try to call int current.
From your posted code, int current is defined in class ListForTrees. However you are trying to access it without initializing your object of type ListForTrees.
In addition, you are using mainlist which is also not defined in your posted code. Please, post complete code coverage of items that you use in code.

Your current variable is encapsulated inside your ListForTrees class. Since this variable is an instance variable, you need to create a new instance of ListForTrees in order to access this variable using the instance.variable syntax.
Moreover I believe your class design is quite flawed. I think what you should redesign your class like:
public class FruitTree
{
public static int Current { get; set; }
public FruitTree GetNextTree()
{
//your code here
}
}
And then you can initialize a list of trees in your code

Related

Is possible to declare multiple times same name variable in c# within Ne-stead/same Scope?

namespace project1
{
public class testclass
{
int i = 0;
public int foobar()
{
int i = 1;
return i;
}
}
}
Result:
1
I am declaring two times of i variable. Why does c# compiler allowing me this ?
If I will try to declare in same scope then compiler will give me exception so why allowing in nested scope?
This is not a bug
Your field int i in the class declaration can be accessed at any time with this.i so there is no overlap. In fact, this is actually the convention to write (private) field names, parameters and local variables within methods in camelCase. Properties, method names, class names etc. on the other hand are written in PascalCase.
So in your class if you want to access the field i of your class, you can do so by writing this.i. Otherwise you will access the scope designated variable i as long as you are within the if-block.
namespace Project1 // PascalCase here for namespace name
{
public class TestClass // Again PascalCase for class name.
{
int i = 0; // camelCase correct here for field name.
public void Foobar() // PascalCase for method name.
{
if (0 == 0)
{
int i = 0; // camelCase correct here for local variable name.
// Cannot be re-declared until your if-block is finished.
// accessing both elements named 'i'
this.i = i;
}
return;
}
}
}
See Microsoft docs for further reference.
All variables declared in a particular scope have to be unique.
You can reuse some variables depending on their data types, but whether or not you should reuse a variable depends on what you're doing.
Your code can work, but you're declaring i a second time which is incorrect as it already exists with a value of 0.
You need to change its value instead of trying to recreate the variable:
namespace project1
{
public class testclass
{
int i = 0;
public void foobar()
{
if (0 == 0)
{
i = 0;
}
return;
}
}
}
You could also create a new variable:
namespace project1
{
public class testclass
{
int i = 0;
public void foobar()
{
if (0 == 0)
{
int j = 0;
}
return;
}
}
}

C# Accessing member variable from one class to another

So I'm working with two files: Simulator and Environment. In the environment file, I have a member variable called "Entities". It is defined there and it has constructor and a get-set function. My Simulator class has that Environment class included in its code; with a constructor and a set-get function for it.
Now I am trying to make the Environment class to work within the Simulator class. The code I have right now is supposed to include the environment member variable "Entities" in a for loop code I wrote inside my Simulator class.
The error I'm receiving is that the variable member doesn't exist in the current context. However I want to let the computer know that the member variable is from the Environment class. How can I fix this error? I'm using C#.
This is the code I'm having problem with:
the run() method, from my simulator class
public void run()
{
for (int i = 0; i < 50 && entities.Count > 1; i++)
{
entities.RemoveAll(m => !m.IsAlive());
step(i);
}
}
Here is the environment class.
#region ENVIRONMENT CLASS
//__________________//
// ENVIRONMENT //
//__________________//
public abstract class ENVIRONMENT
{
private List<ENTITY> entities;
public ENVIRONMENT()
{
entities = new List<ENTITY>();
}
public void AddEntity(ENTITY e)
{
entities = new List<ENTITY>();
entities.Add(e);
Random rand = new Random();
foreach (ENTITY element in entities)
{
int locX = rand.Next(0, 9);
int locY = rand.Next(0, 9);
element.X = locX;
element.Y = locY;
//element.LocalPoint.X = locX;
//element.LocalPoint.Y = locY;
}
}
public ICollection<ENTITY> Population
{
get { return entities; }
}
}
EDIT: Earlier I gave another name for Entities and that was List, so I changed it.
I don't see a field named LIST, but I do see a field named entities, of type LIST<ENTITY>.
Add an internal or public get property accessor for your entities variable, and initialize entities to an empty list upon class instantiation.
Also, why are all of your class names (apparently) fully UPPERCASE?
public abstract class ENVIRONMENT
{
private List<ENTITY> entities = new List<ENTITY>();
public List<ENTITY> Entities
{
get { return entities; }
}
...
}

How to call a function from one script attached to a game object to another in C#?

Basically I have one script set up which during play prints to the console.
//Method to loop find question to be asked and print it as well as loop through answerText and print the appropriate answer options/
public void AskNewQuestion ()
{
//prints Person: + apropriate question based on questionUpTo.
Debug.Log ("Person:" + questionsText [questionUpTo]);
//Loops through answersText and compares it to questionUpTo to find applicable answers.
for (int i = 0; i < answerText[questionUpTo].Count; i++)
{
//Prints applicable answers to console.
Debug.Log(i+1 + ":" + answerText[questionUpTo][i]);
}
}
Now I need this to print not to the console, but through another script which handles a canvas, and the canvas is where I need the text to print to.
public class Textboxmanager : MonoBehaviour {
public GameObject textBox;
public Text theText;
public TextAsset textFile;
public string[] textLines;
public int currentLine;
public int endAtLine;
public bool isActive;
// Use this for initialization
void Start ()
{
if(textFile != null)
{
textLines = (textFile.text.Split('\n'));
}
if(endAtLine == 0)
{
endAtLine = textLines.Length - 1;
}
if(isActive)
{
EnableTextBox();
}
else
{
DisableTextBox();
}
}
void Update()
{
if(!isActive)
{
return;
}
theText.text = textLines[currentLine];
if(Input.GetKeyDown(KeyCode.Return))
{
currentLine += 1;
}
if(currentLine > endAtLine)
{
DisableTextBox();
}
}
public void EnableTextBox()
{
textBox.SetActive(true);
}
public void DisableTextBox()
{
textBox.SetActive(false);
}
}
There are many ways in which you can accomplish this. First of all, i notice that the script from which you are trying to print to is a manager of sorts. In that case there is a high level concept called Singletons.
Here is a link on how to implement Singletons in C-Sharp:
https://unity3d.com/learn/tutorials/projects/2d-roguelike-tutorial/writing-game-manager
Watch the unity video on them and make sure this is the right approach to your problem.
If you don't want to go down that complex path and would rather avoid the headache then i will try and explain how to reference another script and all of its functions, variables and other data without singletons.
Class1 {
public Class2 class2Reference;
private void printTextFromClass2() {
class2Reference.printAnswerText();
}
}
Class2 {
public void printAnswerText() {
Debug.Log("String");
}
}
In this example you can see that i have two classes, these may be in different scripts and on completely different gameObjects within Unity. We created a variable with the datatype as the class name we are trying to access. In this case the datatype is Class2. We then use it as a variable any time that we need to access that script.
The only thing that you must do is give it a script to reference. Much like a string is null until we give it a value, our variable 'private Class2 class2Reference' is null until we give it a value.
This is the easy part. Save and go back to unity. You should see your variable in the inspector with "none" written next to it. Drag and drop your second script into that box and you should be ready to rumble.
Hope this helps you out buddy.
Instantiate the AskNewQuestion class inside the TextboxManager class.
puclic TextboxManager : Monobehavior {
AskNewQuestion askNewQuestion = new AskNewQuestion();
}
Make a function inside AskNewQuestion that returns the array string. Then call it on the TextboxManager class to get the array string. Like this: textLines = askNewQuestion.questions;.
Edit: You can use a { get; set; } method with this. First initialize on where you store the string array then apply it on the { get; set; } method.
string[] questions;
public string[] Questions {
get {
return quesions;
}
}

Static Initialization is not working with c# and xaml

Here is the problem. I made a class of enums to track difficulty level. When I pass the level in my main It does not get passed into my OtherPage. here is my code public sealed class GlobalVars
{
public enum Difficulty
{
Easy,
Intermediate,
Hard
}
private static readonly GlobalVars instance = new GlobalVars();
private GlobalVars() { }
public static GlobalVars Instance
{
get
{
return instance;
}
}
}
Here is what I am doing in my main page
private void Easy_Checked(object sender, RoutedEventArgs e)
{
GlobalVars.Difficulty _difficulty = GlobalVars.Difficulty.Easy;
//_difficulty = GlobalVars.Difficulty.Easy;
}
Next I go to my divisionPage and do the following
initialize an instance of the class
private GlobalVars.Difficulty _difficulty;
then
if ( _difficulty == GlobalVars.Difficulty.Easy)
{
do something easy
}
if ( _difficulty == GlobalVars.Difficulty.Hard)
{
do something hard
}
My enum value is always easy not able to pass the other levels to this page.
First of all, you not are using Enum incorrectly. Difficulty is an enum(type).
Second, you are not using the GlobalVars instance at all, you are always working with a local variable. Instance property has to be used to use the instance and then set the values at the level of instance.
GlobalVars.Difficulty _difficulty = GlobalVars.Difficulty.Easy;
Above statement assigns value to only the variable _difficulty but not to the static instance. If you need to carry the state or set the difficulty value, use some instance\member level variable like,
public Difficulty DifficultySet { get; set; }
Set the instance's DifficultySet from MainPage, access this value from any other page. Since you have singleton (one instance only), value set from Main page would be available with the instance.
Complete code would look like below. [Please write your own code to understand, how static, enums and instantiation works.]
public sealed class GlobalVars
{
static readonly GlobalVars instance = new GlobalVars();
public Difficulty DifficultySet { get; set; }
private GlobalVars()
{
}
public static GlobalVars Instance
{
get
{
return instance;
}
}
public enum Difficulty { Easy, Intermediate, Hard };
}
//main page
GlobalVars pageInstance = GlobalVars.Instance;
pageInstance.DifficultySet = GlobalVars.Difficulty.Easy;
//other page
if(GlobalVars.Instance.DifficultySet == GlobalVars.Difficulty.Easy)
{
//write your logic
}

Cannot Add to generic list

Firstly I apologise for the oversimplification, but I have this issue which is driving me crazy. It should work - it's simple code, nothing fancy.......
I have this object
public class Stuff
{
private int intStuff;
private string strStuff;
public Stuff(int StuffID, string Stuff)
{
intStuff = StuffID;
strStuff = Stuff;
}
public int StuffID
{
get { return intStuff; }
set { intStuff = value; }
}
public string Stuff
{
get{return strStuff;}
set{strStuff=value;}
}
}
Which is used in this class:
public class StuffandThings
{
private List<Stuff> lstMyStuff;
public List<Stuff> StuffList
{
set { lstMyStuff = value; }
get { return lstMyStuff; }
}
public StuffandThings()
{
lstMyStuff = new List<Stuff>();
}
}
Which is declared as a static in Global.asax <<<< this may be important
public static StuffAndThings MyStuff;
protected void Application_Start(object sender, EventArgs e)
{
MyStuff = new StuffandThings();
}
And when I use it in code:
foreach (string strStuff in lstStuff)
{
objStuff = new Stuff(intStuff,strStuff);
Global.MyStuff.StuffList.Add(objStuff);
}
It compiles and I can run in debug (it's a WCF Web service), my variables (intStuff and lstStuff) are all valid.but when I click on Service.svc in the browser I get the following error.
CS1502: The best overloaded method match for 'System.Collections.Generic.List.Add(Stuff)' has some invalid arguments
I don't think I can see the wood for the trees with this one and the interwebs have been no help.
Aso, all my other objects and functions in the global object are fine - hashtables mostly, and my code ran until I tried to add this functionality. I would use a hashtable but I would need the key to not be unique;
Any Ideas, please?
Thanks
P
You should declare the type of objStuff inside the loop. Always declare variables inside the smallest scope you can:
Stuff objStuff = new Stuff(intStuff,strStuff);
Global.MyStuff.StuffList.Add(objStuff);
If this fails to compile because objStuff is already in use in the parent scope then find a new name - objStuff2 for example, then everything should work.
Where is objStuff declared in your code? You might be picking up the declaration of something else that also happens to be called objStuff but is actually unrelated.

Categories

Resources