C# warning: "The variable is assigned but its value is never used" - c#

I am a first-timer learning C# and I just started writing my first program. I am currently running into a snag in one of my while loops. Normally I find that outside the loop my variables work like they should, but for some reason Visual Studio is giving me a warning saying that "The variable 'itemPrice' is assigned but its value is never used."
How I can I get that warning to go away and avoid any kind of bad practices?
using System;
class Program
{
public static void Main()
{
// "whoa" <-- string literal
// 43 <-- int literal
// 43.34 <-- double literal
// false <-- bool literal
// 43.4f <-- float literal
// 43f <-- float literal
// 43m <-- decimal literal
bool hasEnteredMoney = false;
decimal money = 0;
int menuSelection;
decimal itemPrice;
bool isValidItem;
string itemName;
while (!hasEnteredMoney)
{
Console.Write("Please enter how much money you have: ");
hasEnteredMoney = decimal.TryParse(Console.ReadLine(), out money);
if (!hasEnteredMoney)
{
Console.WriteLine("Please enter a valid decimal value.");
}
}
while (money >= 3)
{
Console.WriteLine("You have $" + money + " left.");
Console.WriteLine("Please enter your selection:");
Console.WriteLine("[0] - Poke Ball - $200");
Console.WriteLine("[1] - Great Ball - $700");
Console.WriteLine("[2] - Ultra Ball - $1200");
Console.WriteLine("[3] - Potion - $300");
Console.WriteLine("[4] - Antidote - $100");
Console.WriteLine("[5] - Clear Mail - $50");
Console.WriteLine(": ");
if (int.TryParse(Console.ReadLine(), out menuSelection))
{
isValidItem = false;
if (menuSelection == 0)
{
itemPrice = 200;
itemName = "Poke Ball";
isValidItem = true;
}
if (menuSelection == 1)
{
itemPrice = 700;
itemName = "Great Ball";
isValidItem = true;
}
if (menuSelection == 2)
{
itemPrice = 1200;
itemName = "Ultra Ball";
isValidItem = true;
}
if (menuSelection == 3)
{
itemPrice = 300;
itemName = "Potion";
isValidItem = true;
}
if (menuSelection == 4)
{
itemPrice = 100;
itemName = "Antidote";
isValidItem = true;
}
if (menuSelection == 5)
{
itemPrice = 50;
itemName = "Clear Mail";
isValidItem = true;
}
}
else
{
Console.WriteLine("Invalid input.");
}
}
Console.WriteLine("... you ran out of money :(");
Console.ReadKey();
}
}

The variables itemPrice, isValidItem, itemName are being set (being assigned to), but the variables are not being used for other purposes later in the program.
The compiler is warning you that although you are setting itemPrice, isValidItem, and itemName, setting these variables is not doing anything in the program - E.G. when the program is executed, the variables will not have any effect on the operation of the program.

It is giving you this error because your variables are never use in the code.
itemPrice = 200;
itemName = "Poke Ball";
isValidItem = true;
So visual studio intellisense is basicly saying : you putting all those values in your variables, but are never using any of them no where.
If you Console.WriteLine(itemName); at the end of you code, the warning should go away for all the itemName in you loop.
tl;dr You set; them but never get; them

The warning is a good indication that you should actually do something with the value. In your case, I think you would want to do something like
money -= itemPrice;
First, it will get rid of the warning.
Second, it will keep the while loop from running indefinitely :)

Related

How to save a variables value when leaving the method?

I have a method which counts the amount of times a user has withdrawn from the atm(as there is a limit) and also counts up the amount of money the user has withdrawn in the day. However the values in the count var and in the amountWithdrawn variable are both lost upon leaving the method, how do I keep them "saved"? Also as a side note, I have a class called Account which has the balance and such, would it be best to put them there? But would also like to know if it is possible to save the variables in the method for future reference.
public decimal WithDraw()
{
int timesWithdrawn = 9;
decimal amountWithdrawnToday = 0;
decimal money = 0;
bool success = false;
if (timesWithdrawn < 10)
{
do
{
//Console.WriteLine("{0} available to withdraw.", FundsAvailable);
Console.WriteLine("How much would you like to withdraw?");
try
{
money = decimal.Parse(Console.ReadLine());
if (money % 5 == 0 && money <= account.CurrentBalance && money <= 1000)
{
success = true;
}
if (money == 0)
{
bool exit = true;
Console.WriteLine("Do you want to exit? Type \"yes\", or \"no\".");
while (exit == true)
{
string response = Console.ReadLine();
if (response.ToLower() == "yes")
{
break;
}
else
{
exit = false;
}
}
}
}
catch (FormatException)
{
Console.WriteLine("Please enter a number to withdraw.");
}
} while (success == false);
//do while this is true
Console.WriteLine(account.CurrentBalance);
Console.WriteLine("Withdrawing {0} pounds.", money);
Console.WriteLine("You have {0} remaining in your account.", account.CurrentBalance - money);
amountWithdrawnToday += money;
timesWithdrawn += 1;
Console.WriteLine("{0} pounds withdrawn today", amountWithdrawnToday);
return account.CurrentBalance -= money;
}
else
{
Console.WriteLine("You have exceeded daily withdrawls. You have withdrawn {0}", amountWithdrawnToday);
return amountWithdrawnToday;
}
}
I will suggest you need to put those variable in the Account class, also I suggest that you could put the withdraw method itself in the Account class, This could be more OOP friendly.
and to save the timesWithdrawn number, you just need to make it as class instance vairable instead of making it local variable
here is the code
class Account
{
public decimal CurrentBalance { get; set; }
public int timesWithdrawn { get; set; } = 9;
public decimal WithDraw()
{
decimal amountWithdrawnToday = 0;
decimal money = 0;
bool success = false;
if (timesWithdrawn < 10)
{
do
{
//Console.WriteLine("{0} available to withdraw.", FundsAvailable);
Console.WriteLine("How much would you like to withdraw?");
try
{
money = decimal.Parse(Console.ReadLine());
if (money % 5 == 0 && money <= CurrentBalance && money <= 1000)
{
success = true;
}
if (money == 0)
{
bool exit = true;
Console.WriteLine("Do you want to exit? Type \"yes\", or \"no\".");
while (exit == true)
{
string response = Console.ReadLine();
if (response.ToLower() == "yes")
{
break;
}
else
{
exit = false;
}
}
}
}
catch (FormatException)
{
Console.WriteLine("Please enter a number to withdraw.");
}
} while (success == false);
//do while this is true
Console.WriteLine(CurrentBalance);
Console.WriteLine("Withdrawing {0} pounds.", money);
Console.WriteLine("You have {0} remaining in your account.", CurrentBalance - money);
amountWithdrawnToday += money;
timesWithdrawn += 1;
Console.WriteLine("{0} pounds withdrawn today", amountWithdrawnToday);
return CurrentBalance -= money;
}
else
{
Console.WriteLine("You have exceeded daily withdrawls. You have withdrawn {0}", amountWithdrawnToday);
return amountWithdrawnToday;
}
}
}
as you notice from the code, I removed the reference to the account variable and made the CurrentBalance as instance variable and also the timesWithdrawn.
this could preserve the value of the timesWithdrawn even after the method has been finished.
As long as the program is running it is saved there, but once quite it resets, so yes you have to save it somewhere in a database a excel table or in a text document
Saving data to a file in C#
check this out if you need some help how to do stuff like this
You could pass an 'out' parameter to the function, it's basically a variable you send to the function, which holds its value outside the function.
For example:
public void WithDraw(out int c) {
c = something ; //c must receive a value during the call
}
int myvar; // the parameter which will hold the value when the function returns
WithDraw(out myvar); //call to the function
myvar //will now hold a value from the function (something)
You could also consider returning a tuple, or putting the value you wish to save into a 'global variable'.

Why looping twice on string length test

I'm working in C# (2013) Windows Forms. My instructor wanted us to ensure that the txtStateInput is upperCase when we hit the calculate button. However when I input a two character string such as "wi" and then hit calculate, it throws the message "enter valid state" and clears out the textbox. When I enter the "wi" in a second time then it works. I can't figure out why this is happening, the code would lead me to believe that it would check to ensure the string in txtStateInput is two characters and then when calculate is clicked it would uppercase the string. I can't figure out why it only works once I enter in the state "wi" a second time.
private void btnCalc_Click(object sender, EventArgs e)
{
//declare variables.
int startPop = 0;
int endPop = 0;
string Message = "Error";
decimal Percent = 0.0m;
string State = "";
string City = String.Empty;
int dTimes = 0;
try
{
City = txtCityInput.Text;
//System Globalization was initialized so this method works.
TextInfo myTI = new CultureInfo("en-US", false).TextInfo;
txtCityInput.Text = myTI.ToTitleCase(City);
if(txtStateInput.Text.Length != 2)
{
MessageBox.Show("Enter valid State");
txtStateInput.Focus();
txtStateInput.SelectAll();
}
else
{
State = txtStateInput.Text.ToUpper();
txtStateInput.Text = State;
if ((int.TryParse(txtStartPopInput.Text, out startPop)) && int.TryParse(txtEndPopInput.Text, out endPop))
{
if ((startPop > 0) && (endPop > 0))
{
//if population has decreased.
if ((startPop > endPop))
{
Percent = ((decimal.Parse(endPop.ToString()) - decimal.Parse(startPop.ToString())) / decimal.Parse(startPop.ToString()));
Message = "Pop. Decrease of " + Percent.ToString("p");
}
//if population has increased.
if ((startPop < endPop))
{
Percent = ((decimal.Parse(endPop.ToString()) - decimal.Parse(startPop.ToString())) / decimal.Parse(startPop.ToString()));
Message = "Pop. Increase of " + Percent.ToString("p");
}
//if population has not changed.
if ((startPop == endPop))
{
Percent = ((decimal.Parse(endPop.ToString()) - decimal.Parse(startPop.ToString())) / decimal.Parse(startPop.ToString()));
Message = "No Change in Population";
}
}
else
{
MessageBox.Show("Please enter valid population figures.");
}
}
if (int.TryParse(txtDisplayTimes.Text, out dTimes))
{
if (dTimes > 0)
{
lstResults.Items.Clear();
int iSum = 0;
int iLoopCount = dTimes;
//displays the results according to value in txtDisplayTimes.
for (iSum = 1; iSum <= iLoopCount; iSum++)
{
lstResults.Items.Add(Message);
}
}
}
}
}
catch
{
MessageBox.Show("Something went wrong.");
}
}

using decimal values in user settings

I'm having some troubles setting decimal values in the settings file, when it asks me for the type of variable I'm choosing the decimal and the default value is 0.10, this is to imitate 10 cents, but when I run my program and check the value of the variable it's showing as 0.01, this is because I should add an "m" at the end and that's not allowed in the settings file. is there some work-around for this?
also the user may set his/her own price that's entered in to a textbox, this for example could be 0.30 (30 cents) how can i convert the textbox value to 0.30m?
using a double is not an option, I don't want to end up with something like $2.99999999 decimal type is perfect if only I could use it in the settings file like I can hard-coded.
Thanks for replies.
public void beginUser(int tblSize)
{
decimal tblPrice = 0.00m;
int minCount = 0;
decimal curCost = 0.00m;
string timeStarted = string.Format("{0:HH:mm:ss tt}", DateTime.Now);
//Setup table price
switch (tblSize)
{
case 0:
tblPrice = Properties.Settings.Default.tblSmallPrice;
//tblPrice = 0.10m //this works
break;
case 1:
tblPrice = Properties.Settings.Default.tblBigPrice;
//tblPrice = 0.15m // this works
break;
default:
tblPrice = 0.10m;
break;
}
//Check how tblPrice appears.
MessageBox.Show(Convert.ToString(tblPrice));
try
{
while (true)
{
Thread.Sleep(100);
curCost += tblPrice;
minCount += 1;
if (minCount == 60) { Thread.CurrentThread.Abort(); }
}
}
catch (ThreadAbortException)
{
TimeSpan span = TimeSpan.FromMinutes(minCount);
string output = String.Format("Cost: €{0}\r\ncurCost: {1} hour(s) {2} minutes\r\nStarted: {3}", curCost, span.Hours, span.Minutes, timeStarted);
MessageBox.Show(output);
}
}
Use commas! It should work:
0.1 becomes 0,1.
Here you can see how I managed to insert it:

C# console application - commission calculator - how to use method within method

I'm new to C# and I have encountered some problems with my console application that I'm recently working on. I am trying to have 3 methods:
getsales to get the sales the user made, calcCom to calculate the commission for the sales and finally main to make them work and establish the program.
I'm having trouble to make those methods work with(in) each other.
After i entered all the sales, the program goes to the else-statement and tells me "invalid entry". Since i haven't really gotten to output the variables I didn't expect any kind of output, but I want the program to tell the user the commission and sale for each person.
Please excuse me if I misused any terms or words, like I said I am new to this language! :D
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication38
{
class Program
{
public static void getsales ()
{
string inputsales;
double total = 0;
double sale = 0;
for (int salecount = 1; salecount <= 3; ++salecount)
{
Console.WriteLine("Enter sale: ");
inputsales = Console.ReadLine();
sale = Convert.ToDouble(inputsales);
total = total + sale;
Console.WriteLine();
}
}
public static void calcComm ()
{
double total = 0;
double comm = 0;
comm = total * 0.2;
}
static void Main()
{
Console.WriteLine(" Sunshine Hot Tubs \n Sales Commissions Report\n");
char Letter;
string name;
const string name1 = "Andreas";
const string name2 = "Brittany";
const string name3 = "Eric";
string inputLetter;
Console.WriteLine("Please enter intial or type z to quit");
inputLetter = Console.ReadLine();
Letter = Convert.ToChar(inputLetter);
while (Letter != 'z')
{
if (Letter == 'a')
{
name = name1;
getsales();
calcComm();
}
if (Letter == 'b')
{
name = name2;
getsales();
calcComm();
}
if (Letter == 'e')
{
name = name3;
getsales();
calcComm();
}
else
{
Console.WriteLine("Invalid entry try again");
inputLetter = Console.ReadLine();
}
}
}
}
}
I think your problem is you need this:
if (Letter == 'a')
{
name = name1;
getsales();
calcComm();
}
else if (Letter == 'b')
{
name = name2;
getsales();
calcComm();
}
else if (Letter == 'e')
{
name = name3;
getsales();
calcComm();
}
else
{
Console.WriteLine("Invalid entry try again");
inputLetter = Console.ReadLine();
}
You also need to copy this code after the else block, at the very end of your while loop.
Console.WriteLine("Please enter intial or type z to quit");
inputLetter = Console.ReadLine();
Letter = Convert.ToChar(inputLetter);
Also, remove this line from inside the else block. It isn't needed.
inputLetter = Console.ReadLine();
You probably intended to display the commision on the console. Change your getsales and calcComm to look like this:
public static void getsales ()
{
string inputsales;
double total = 0;
double sale = 0;
for (int salecount = 1; salecount <= 3; ++salecount)
{
Console.WriteLine("Enter sale: ");
inputsales = Console.ReadLine();
sale = Convert.ToDouble(inputsales);
total = total + sale;
Console.WriteLine();
}
calcComm(total);
}
public static void calcComm (double total)
{
double comm = 0;
comm = total * 0.2;
Console.WriteLine(comm);
}
Then remove all calls to calcComm from the Main method.
The variable "total" is in the two methods and they do not persist the data that you are looking for between the two methods that you have defined. That is, the total variable in getSales() method is different from calcComm() method.
You should move this:
double total = 0;
outside of the two methods and put it within the class with a static scope. Like:
class Program
{
static double total;
Also, reinitialize total to zero within your getSales() method.
calcComm() doesn't do anything...
I think you might want to have some of your variables as global so that if they are modified by a method you can still retrieve their value, or even better pass them to the method and get them returned with the new values.
To declare global variables you should declare them inside the class Program but outside any method and then make sure that no other methods have variables with the same name

What does "Use of unassigned local variable" mean?

This question already has answers here:
Why did I get the compile error "Use of unassigned local variable"?
(10 answers)
Closed 4 days ago.
I keep getting this error for annualRate, monthlyCharge, and lateFee.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Lab_5___Danny_Curro
{
class Program
{
static void Main(string[] args)
{
string firstName;
string lastName;
int accNumber;
string creditPlan;
double balance;
string status;
Boolean late = false;
double lateFee;
double monthlyCharge;
double annualRate;
double netBalance;
Console.Write("Enter First Name: ");
firstName = Console.ReadLine();
Console.Write("Enter Last Name: ");
lastName = Console.ReadLine();
Console.Write("Enter Account Number: ");
accNumber = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter Credit Card Plan Number[Blank Will Enter Plan 0]: ");
creditPlan = Console.ReadLine();
Console.Write("Enter Balance: ");
balance = Convert.ToDouble(Console.ReadLine());
Console.Write("Is This Account Late?: ");
status = Console.ReadLine().Trim().ToLower();
if (creditPlan == "0")
{
annualRate = 0.35; //35%
lateFee = 0.0;
monthlyCharge = balance * (annualRate * (1 / 12));
return;
}
if (creditPlan == "1")
{
annualRate = 0.30; //30%
if (status == "y")
{
late = true;
}
else if (status == "n")
{
late = false;
}
if (late == true)
{
lateFee = 25.00;
}
monthlyCharge = balance * (annualRate * (1 / 12));
return;
}
if (creditPlan == "2")
{
annualRate = 0.20; //20%
if (status == "y")
{
late = true;
}
else if (status == "n")
{
late = false;
}
if (late == true)
{
lateFee = 35.00;
}
if (balance > 100)
{
monthlyCharge = balance * (annualRate * (1 / 12));
}
else
{
monthlyCharge = 0;
}
return;
}
if (creditPlan == "3")
{
annualRate = 0.15; //15%
lateFee = 0.00;
if (balance > 500)
{
monthlyCharge = (balance - 500) * (annualRate * (1 / 12));
}
else
{
monthlyCharge = 0;
}
return;
}
netBalance = balance - (lateFee + monthlyCharge);
Console.WriteLine("Name: \t\t\t {0} {1}", firstName, lastName);
Console.WriteLine("Account Number: \t{0}", accNumber);
Console.WriteLine("Credit Plane: \t\t{0}",creditPlan);
Console.WriteLine("Account Late: \t\t{0}", late);
Console.WriteLine("Balance: \t\t{0}", balance);
Console.WriteLine("Late Fee: \t\t{0}", lateFee);
Console.WriteLine("Interest Charge: \t{0}", monthlyCharge);
Console.WriteLine("Net Balance: \t\t{0}",netBalance);
Console.WriteLine("Annual Rate: \t\t{0}", annualRate);
Console.ReadKey();
}
}
}
The compiler isn't smart enough to know that at least one of your if blocks will be executed. Therefore, it doesn't see that variables like annualRate will be assigned no matter what. Here's how you can make the compiler understand:
if (creditPlan == "0")
{
// ...
}
else if (creditPlan == "1")
{
// ...
}
else if (creditPlan == "2")
{
// ...
}
else
{
// ...
}
The compiler knows that with an if/else block, one of the blocks is guaranteed to be executed, and therefore if you're assigning the variable in all of the blocks, it won't give the compiler error.
By the way, you can also use a switch statement instead of ifs to maybe make your code cleaner.
Change your declarations to this:
double lateFee = 0.0;
double monthlyCharge = 0.0;
double annualRate = 0.0;
The error is caused because there is at least one path through your code where these variables end up not getting set to anything.
Because if none of the if statements evaluate to true then the local variable will be unassigned. Throw an else statement in there and assign some values to those variables in case the if statements don't evaluate to true. Post back here if that doesn't make the error go away.
Your other option is to initialize the variables to some default value when you declare them at the beginning of your code.
Give them a default value:
double lateFee=0.0;
double monthlyCharge = 0.0;
double annualRate = 0.0;
Basically, all possible paths don't initialize these variables.
Use the keyword "default"!!!
string myString = default;
double myDouble = default;
if(!String.IsNullOrEmpty(myString))
myDouble = 1.5;
return myDouble;
There are many paths through your code whereby your variables are not initialized, which is why the compiler complains.
Specifically, you are not validating the user input for creditPlan - if the user enters a value of anything else than "0","1","2" or "3", then none of the branches indicated will be executed (and creditPlan will not be defaulted to zero as per your user prompt).
As others have mentioned, the compiler error can be avoided by either a default initialization of all derived variables before the branches are checked, OR ensuring that at least one of the branches is executed (viz, mutual exclusivity of the branches, with a fall through else statement).
I would however like to point out other potential improvements:
Validate user input before you trust it for use in your code.
Model the parameters as a whole - there are several properties and calculations applicable to each plan.
Use more appropriate types for data. e.g. CreditPlan appears to have a finite domain and is better suited to an enumeration or Dictionary than a string. Financial data and percentages should always be modelled as decimal, not double to avoid rounding issues, and 'status' appears to be a boolean.
DRY up repetitive code. The calculation, monthlyCharge = balance * annualRate * (1/12)) is common to more than one branch. For maintenance reasons, do not duplicate this code.
Possibly more advanced, but note that Functions are now first class citizens of C#, so you can assign a function or lambda as a property, field or parameter!.
e.g. here is an alternative representation of your model:
// Keep all Credit Plan parameters together in a model
public class CreditPlan
{
public Func<decimal, decimal, decimal> MonthlyCharge { get; set; }
public decimal AnnualRate { get; set; }
public Func<bool, Decimal> LateFee { get; set; }
}
// DRY up repeated calculations
static private decimal StandardMonthlyCharge(decimal balance, decimal annualRate)
{
return balance * annualRate / 12;
}
public static Dictionary<int, CreditPlan> CreditPlans = new Dictionary<int, CreditPlan>
{
{ 0, new CreditPlan
{
AnnualRate = .35M,
LateFee = _ => 0.0M,
MonthlyCharge = StandardMonthlyCharge
}
},
{ 1, new CreditPlan
{
AnnualRate = .30M,
LateFee = late => late ? 0 : 25.0M,
MonthlyCharge = StandardMonthlyCharge
}
},
{ 2, new CreditPlan
{
AnnualRate = .20M,
LateFee = late => late ? 0 : 35.0M,
MonthlyCharge = (balance, annualRate) => balance > 100
? balance * annualRate / 12
: 0
}
},
{ 3, new CreditPlan
{
AnnualRate = .15M,
LateFee = _ => 0.0M,
MonthlyCharge = (balance, annualRate) => balance > 500
? (balance - 500) * annualRate / 12
: 0
}
}
};
Your assignments are all nested within your conditional if blocks which means that there is potential for them to never be assigned.
At the top of your class, initialise them to 0 or some other value
The compiler is saying that annualRate will not have a value if the CreditPlan is not recognised.
When creating the local variables ( annualRate, monthlyCharge, and lateFee) assign a default value (0) to them.
Also, you should display an error if the credit plan is unknown.
Not all code paths set a value for lateFee. You may want to set a default value for it at the top.
You don't assign values outside of the if statements ... and it is possible that credit might be something other than 0, 1, 2, or 3, as #iomaxx noted.
Try changing the separate if statements to a single if/else if/else if/else. Or assign default values up at the top.
If you declare the variable "annualRate" like
class Program
{
**static double annualRate;**
public static void Main() {
Try it..

Categories