This question already has an answer here:
c# calling method with array parameters [closed]
(1 answer)
Closed 1 year ago.
My code looks like this:
void Update()
{
if (Input.GetKeyDown(KeyCode.G) && questCount == 6)
{
Score(sumFinal);
}
}
public int Score(int sumFinal)
{
sumFinal = dCount - rCount;
return sumFinal;
}
Visual Studio tells me sumFinal doesn't exist in the current context.
How can I return sumFinal within Update() successfully? Am I understanding parameters correctly?
Additional Question:
Below further down the Score() function, I set text to certain values:
public int Score(int sumFinal)
{
sumFinal = dCount - rCount;
return sumFinal;
if (sumFinal == 5 && questCount >= 5)
{
labelText.text = "results";
}
}
When calling this function in Update(), is there a way I can run both the if statement and the sumFinal subtraction equation separately? In short, how do I segment the function, and call only specific parts of it? Should the return type be set to void?
Visual Studio tells me sumFinal doesn't exist in the current context. How can I return sumFinal within Update() successfully? Am I understanding parameters correctly?
The method Score looks great! However, when you call it Score(sumFinal); you need to make sure that you're passing a value to the method. In your case you may have forgotten to have a field with the value at the top of the class.
is there a way I can run both the if statement and the sumFinal subtraction equation separately?
Sure! What you could do, since you don't actually give Score any value when you call it, you can remove that parameter and just return the value that it calculates.
The we could separate updating the text to another method called UpdateTextBox() that takes the result of Score() to determine if it should change the text or not
public class YourUnityClass : MOnoBehaviour
{
int questCount = 0;
int sumFinal = 0; // make sure that if you need to access this variable between methods that this field exists
int dCount = 0;
int rCount = 0;
public TextMesh labelText;
void Update()
{
if (Input.GetKeyDown(KeyCode.G) && questCount == 6)
{
// calculate and save the score
sumFinal = Score();
// check the score, and update the text if necessary
UpdateTextBox(sumFinal);
}
}
public int Score()
{
// calculate the score
return dCount - rCount;
}
public void UpdateTextBox(int sumFinal)
{
// check to see if the score is high enough to change
// the text
if (sumFinal == 5 && questCount >= 5)
{
labelText.text = "results";
}
}
}
Related
IDE: Visual Studio 2015 Update 3
Language: C# / .NET 4.5
Situation: Suppose I defined a class and I'm calling its properties tens of times, further let's suppose the class operates over one input given to the constructor and therefore it makes all operations except the first one redundant, because we already managed to calculate the return value the first time we called it.
Example of such property:
// let's call it a Month, because it extracts a month code from a string
private int Month
{
// there is only a getter
get
{
// here's my current strategy
// in the beginning of the class I set fMonth to -1
// it can only have possitive numbers, so if already set, I return it
if (fMonth > -1)
return fMonth;
// and here's the part I don't want to repeat
return fMonth =
Convert.ToInt32(SomeNumberString.Substring(2, 2));
}
}
Question: Is this the right strategy for not repeating the executive code?
Since the value for someNumberString is given to you in the constructor, you can use a readonly property.
ctor(string someNumberString)
{
Month = Convert.ToInt32(someNumberString.Substring(2, 2));
}
public Month { get; }
You are on the right track with using a private backing field fmonth for the property. You can further optimize this by moving the conversion code to an explicit set method. This removes the if check from every get access.
ctor(string someNumberString) {
SetMonth(someNumberString);
}
private int Month { get { return fmonth; } }
// -1 indicates that SetMonth() has never been called
private int fmonth = -1;
public void SetMonth(string someNumberString) {
fmonth = Convert.ToInt32(someNumberString.Substring(2, 2));
}
I have a 'Movie' class in my C# code that has an int[] ratings = new int[10]; as a field. I would like to place numbers in this empty array from my main program.
For that, I would need a method, that could point to the actual free index of the array to put the integer there, but the other integer that would point to the free index would be reset to 0 everytime the method is called. Thus, my question is, that how can I place an integer in my method that is increased everytime the method was called.
This is the method in the class:
public void Rate(int rating)
{
int x = 0;
ratings[x] = rating;
}
This is how I call it in the main program
Movie asd = new Movie(blabla...);
Rate.asd(1);
Rate.asd(1);
Rate.asd(1);
So I called it 3 times, and I would want the 'x' integer in the class's method to increase.
Thanks in advance.
First of all, you have an error in the code you have posted.
As I suppose rather than:
Movie asd = new Movie(blabla...);
Rate.asd(1);
Rate.asd(1);
Rate.asd(1);
you want to paste here:
Movie asd = new Movie(blabla...);
asd.Rate(1);
asd.Rate(1);
asd.Rate(1);
As C# does not allow to use static method variables (like i.e. C++ does) you have two options:
first, make x value (from Rate method) a Movie's class variable, so Rate method will "remember" the next index,
second (and better) rather than intiger array - if possible use any kind of list or queue (which can manage indexing for you).
The problem is that local variables are discarded when exiting a method.
class SomeClass
{
private int x = 42;
public void DoSometing(int y)
{
int a = y + 5;
x += a * a;
// a stops to exist here
}
}
Solution is to store the variable in the containing class as well
class SomeOtherClass
{
private int x = 42;
private int a = 0;
public void DoSomething(int y)
{
a = y + 5;
x += a * a;
}
}
Now SomeOtherClass remembers the value of a. That's basically the point of member variables a.k.a. fields - to store the state of the object.
More appropriate for your problem:
class ClassWithAnArrayAndCount
{
private int[] values = new int[10];
private int taken = 0;
public void Add(int value)
{
if (taken == 10)
throw new ArgumentOutOfRangeException(); // sorry, no more space
values[taken++] = value;
}
public int Taken { get { return taken; } }
}
I'm having some trouble understanding why my variable has a null value.
Here's my class constructor:
private GraphNode current;
private GraphNode goal;
private GraphNode start;
private List<GraphNode> path;
private List<GraphNode> origin;
public Graph()
{
current = new GraphNode(0, 0);
goal = new GraphNode(0, 0);
start = new GraphNode(0, 0);
path = new List<GraphNode>();
origin = new List<GraphNode>();
}
Defenition of method SetPathing:
public void SetPathing(int mouseX, int mouseY)
{
if (Contains((int)mouseX / 32, (int)mouseY / 32))
{
goal = GetNode((int)mouseX / 32, (int)mouseY / 32);
current = goal;
path.Add(current);
while ((current.X != start.X) && (current.X != start.X))
{
current = origin.Where(keyValuePair => (keyValuePair.Key.X == current.X) && (keyValuePair.Key.X == current.Y)).Select(keyValuePair => keyValuePair.Value).LastOrDefault();
path.Add(current);
}
}
}
When I break on the start of the while-loop in SetPathing I see the following info in the locals screen:
current null PathFinding.GraphNode
goal {PathFinding.GraphNode} PathFinding.GraphNode
X 0 int
x 0 int
Y 5 int
y 5 int
How is that possible after having clearly assigned the reference value of goal to current?
I'm probably missing something stupid here, but I haven't found it after looking for two hours. No asynchronous going on here.
EDIT: Didn't want to be overtly verbose with my initial question, here's some extra details, my apologies. Here are the details of Contains, GetNode and GetNodeIndex. Nothing fancy, I'm an amateur.
public int GetNodeIndex(int x, int y)
{
// Find the node index in the list based on x and y
// Return -1 if not found
return nodes.FindIndex(n => (n.X == x) && (n.Y == y));
}
public GraphNode GetNode(int x, int y)
{
// Find the node in the list based on x and y
// Return null if not in list
int nodeIndex = GetNodeIndex(x, y);
if (nodeIndex != -1)
{
return nodes[nodeIndex];
}
return null;
}
public bool Contains(int x, int y)
{
// Check if the returned value is not -1
if (GetNodeIndex(x, y) != -1)
{
return true;
}
}
The usecase is litterally just along the lines of the following:
using System;
namespace Graphs
{
class Program
{
static void Main()
{
Graph graph = new Graph(20, 20);
graph.SetPathing(Mouse.GetState().X, Mouse.GetState().Y);
}
}
}
Let's dissect your code here.
goal = GetNode((int)mouseX / 32, (int)mouseY / 32);
Here, you've set the variable goal to point to a GraphNode object. So, for the sake of simplicity, we'll call it A. At this point your values look like this:
goal -> A
current -> null
Next, you do this:
current = goal;
And now, your values look like this:
goal -> A
current -> A
Later during your while loop, you call this:
current = origin.Where(keyValuePair => (keyValuePair.Key.X == current.X) && (keyValuePair.Key.X == current.Y)).Select(keyValuePair => keyValuePair.Value).LastOrDefault();
For the sake of simplicity, we'll call the result of this where clause B. So, now your values look like this:
goal -> A
current -> B
All that you have done here is change current to point to a new value.
You showed the code for the default Graph constructor,
public Graph()
not the one being used.
Graph graph = new Graph(20, 20);
Is there any difference between them?
Also, are you sure your code is in sync with the assembly? i.e. from your description it seems your break point is on this line
while ((current.X != start.X) && (current.X != start.X))
Are you sure when you were debugging, it was indeed executing only upto here when the debugger stopped, or it could have already executed the filtering code two lines down?
I'm not sure how this is possible, but the answer appears to be that this is in fact not the first iteration of the While-loop.
I had my break point set to the loop, and the results I posted above were from the first hit of that break point. However, after adding a variable that acted as an iteration counter it turned out this was in fact NOT the first iteration, but the third one. Following this discovery I went on to improve the code in the while loop to prevent current being set to null.
I'm not sure how this could happen. I'm using Visual Studio 2013 Express for Desktop. Never encountered anything like this before.
I have made a programm in c#.
In the code I've made an int called: Paying
but when I try to give it a value, it says the following error:
An object reference is required for the non-static field, method or
property
'Mc_Donalds.Program.Paying'
any suggestions on what I should do?
public int Paying;
// Select what meal you want
Console.WriteLine("To order please type the number infront of the item.");
int Keuze = Convert.ToInt32(Console.ReadLine());
if (Keuze == 1)
{
Paying = 5;
}
else if (Keuze == 2)
{
Paying = 3.50;
}
else if (Keuze == 3)
{
Paying = 1;
}
else if (Keuze == 4)
{
Paying = 6;
}
I'd think your method that does this is static while your int (Paying is not)
There are two ways with which you can access a variable in object oriented world
You should create an object for the class where you declare this variable or make this Field a static field.
The variable in question is Paying.
try to change the declaration of Paying from public int Paying; to something like this
public static int Paying;
Then use it as Program.Paying = 5 or Program.Paying = 3.5 etc assuming your class name in Program
I am attempting to understand how methods work, and I thought that I had it down but it seems that I do not as my RunSelect(); method is not doing what I hoped. On line #19, I ask the user to select value (1 or 2) and return that as an int (Run). Then on line #25 we do an if/if else/else statement depending on the int selected. regardless of what is selected, the int is not recognized and asks the user to try again - no matter what i enter, it is not recognized so my console methods fail and I am not sure what it is I am doing wrong.
I've tried tracing through my code, printing it out to analyze it, took the night to sleep on it. etc. I'm lost as to why it's not working. I'm newb, any help greatly appreciated. I don't think the problem is with my loops or methods, i think it's in how i'm handing off the int to the if statement. But i'm lost as to why it's not working as i thought it would.
thanks and cheers to all for any help
This is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace a032_Factorial_Fibonacci_Sequencer
{
class Program
{
String command = "";
//Need to get the runSelect to work as method
public void Play()
{
Announcer("+ + + Welcome To MegaCorps Factorial Fibioci Sequencer + + +\n\n");
int run = 0;
do
{
RunSelect(run);
if (run == 1) { RunFact(); }
else if (run == 2) { RunFib(); }
else
{
Announcer("Non Valid Selection");
RunSelect(run);
}
Announcer("Enter 'Y' to Run another sequence? ");
command = Console.ReadLine().ToLower().Trim();
}
while (command == "y" || command == "yes");
}
//HelperMethods
public String Announcer(String strTxt)
{
Console.WriteLine(strTxt);
return strTxt;
}
public int RunSelect(int run)
{
Announcer("Enter '1' to run Factor | Enter '2' to run Fibioci");
run = int.Parse(Console.ReadLine());
return run;
}
public void Closer()
{ Console.Read(); }
public void RunFact()
{
//craft program to factor a number entered and return factor
//use double not int to handle factored numbers larger then 57+
Console.WriteLine("Factorial Sequencer Entered/n/n");
Announcer("Enter A Number to FACTOR: ");
double num = double.Parse(Console.ReadLine());
double numNew = 1;
for (int i = 1; i <= num; i++)
{ numNew = numNew * i; }
Announcer("\nFACTORED result: " + numNew);
}
public void RunFib()
{
//craft program to fib a number entered and return fib
//use double not int to handle factored numbers larger then 57+
Console.WriteLine("Fibioci Sequencer Entered\n");
Announcer("Enter A Number to FIBIOC: ");
double iSequence = double.Parse(Console.ReadLine());
Announcer("\nFIBIOC result: ");
double iPrevious = -1;
double iNext = 1;
for (int i = 1; i <= iSequence; i++)
{
double iSum = iNext + iPrevious;
iPrevious = iNext;
iNext = iSum;
Console.Write(iNext + ", ");
}
}
static void Main(string[] args)
{
Program myProgram = new Program();
myProgram.Play();
}
}
}
Problem : you are not storing the return value of the RunSelect() method.
Solution : You need to store the return value of the RunSelect() Method.otherwise variable run value will not be modified (still zero even after calling RunSelect() method).
Replace This:
RunSelect(run);
WIth This:
run=RunSelect(run);
EDIT: if you are calling a method which returns something then you need to read/store the return value of that method as it contains modified value.
Step 1: in your code you have initialised variable run using following statement:
int run = 0;
Step 2: inside do-while loop you have called RunSelect() method as below:
do
{
RunSelect(run);
------
Step 3: in the method RunSelect() you are assigning the run variable with actual userinput given from console using following statements:
Note: here run variable in RunSelect() method is local variable to that method so even if you assign value to run it wont be reflected to run variable declared in Play() function.
public int RunSelect(int run)
{
Announcer("Enter '1' to run Factor | Enter '2' to run Fibioci");
run = int.Parse(Console.ReadLine());/here you are assigning userinput to run variable.
return run;
}
Step 4: you are sending back the modified variable value run to the caller of this method(RunSelect()):
Step 5: there you are not storing this return value sent by RunSelect() method again into run variable as below:
RunSelect(run);
so still run variable will have the initialised value zero.
to make it work you need to just store the return value of the RunSelect() method as below:
run=RunSelect(run);
You have a Function which accepts a value parameter and returns an int, but you aren't assigning the return int to anything. In your case, the parameter is redundant, since it isn't used within the method anyway. in C#, by default, parameters are value parameters. This means that a new storage location is created for the variable in the function member declaration, and it starts off with the value that you specify in the function member invocation. If you change that value, that doesn't alter any variables involved in the invocation.
try this instead:
public int RunSelect()
{
Announcer("Enter '1' to run Factor | Enter '2' to run Fibioci");
int run = int.Parse(Console.ReadLine());
return run;
}
and in your method call:
int run = RunSelect();
no need to pre-initialize run before the call, so you can remove the line int run = 0;
When you call RunSelect(run), you are not changing the current value of run. Passing in run cannot change its value. The RunSelect function returns a new value that you have to assign like this: run = RunSelect(run).
Also you will notice that RunSelect does not use the value of run that is passed in, so it can just as easily be written like this:
public int RunSelect()
{
Announcer("Enter '1' to run Factor | Enter '2' to run Fibioci");
int run = int.Parse(Console.ReadLine());
return run;
}