String inside an if statement [duplicate] - c#

I have this var, but I want to change it's content depending on the statement, I can't get it working because when I use it, VS says it has not been declared, even if the statement is true...
if (DateTime.Today.Day > 28 && DateTime.Today.Day < 2)
{
var days = GetDaysLikeMe(DateTime.Today).Take(50).Where(d => d.Date.Day > 28 && d.Date.Day < 2).Take(4);
}
else
{
var days = GetDaysLikeMe(DateTime.Today).Take(50).Where(d => d.Date.Day < 28 && d.Date.Day > 2).Take(4);
}
EDIT:
I've tried to declare the variable outside the box... But can't get it working neither, the function I keep on var days is this
public IEnumerable<DateTime> GetDaysLikeMe(DateTime currentDate)
{
DateTime temp = currentDate;
while (true)
{
temp = temp.AddDays(-7);
yield return temp;
}
}

Declare the variable outside the scope of the if statement:
IEnumerable<DateTime> days;
if (DateTime.Today.Day > 28 && DateTime.Today.Day < 2)
{
days = GetDaysLikeMe(calendario.Value.Date).Take(50).Where(d => d.Date.Day > 28 && d.Date.Day < 2).Take(4);
}
else
{
days = GetDaysLikeMe(calendario.Value.Date).Take(50).Where(d => d.Date.Day < 28 && d.Date.Day > 2).Take(4);
}

Declare the variable outside the if block (without assigning a value - you can't use var in this case though, you'll have to specify the type), and then only assign a value to it inside.

There is nothing wrong with your code as it is now - you can easily define varables with var or explicitly specifying type inside any block, including if.
What likely happens is that you are trying to use this varable outside the block it is defined (i.e. after if statement) which is where days becomes undefined.
Fix: define variable outside the if, but you need explicit type there. If you have ReSharper it allows easily change between var/explicit type. Otherwise you'll have to figure out type yourself (in your case it is liklye IEnumerable<DateTime>).

Related

Use of unassigned local variable being a pain

I'm trying to make a program that finds the factors of a number. I made a fairly simple one but it always repeated the same two factors twice i.e. 1 and 2, 2 and 1. So, to fix that I tried to check if the number had been used before but it keeps saying the bool proceed is unassigned.
using System;
namespace FactorableOrNah
{
class MainClass
{
public static void Main (string[] args)
{
Console.WriteLine ("Enter a whole number to view its factors: ");
int userInput = int.Parse(Console.ReadLine ());
int[] antiDoubler = new int[userInput];
bool proceed;
Console.Clear();
for (int i = 1; i != userInput; i++) {
antiDoubler[i] = userInput / i;
for(int j = 0; j < userInput; j++) {
if (antiDoubler [j] == i)
proceed = false;
else
proceed = true;
}
if ((userInput % i) == 0 && i != 1 && proceed == true)
Console.WriteLine("{0} and {1}", i, (userInput / i));
}
}
}
}
Using uninitialized variables in C# is not allowed. The compilation error can be solved by using either:
bool proceed = false;
or
bool proceed = default(bool);
since the default value of bool is false;
However, the algorithm is too complicated and very hard to read. Just for fun. A recursive example.
static IEnumerable<int> GetFactors(int number)
{
return GetFactors(number, number);
}
static IEnumerable<int> GetFactors(int number, int check)
{
if (check > 0)
{
if (number % check == 0)
{
yield return check;
}
foreach (var f in GetFactors(number, --check))
{
yield return f;
}
}
}
UPDATE:
Local variables cannot be left uninitialized, however class members (static members and instance variables), furthermore array elements are initialized automatically by the memory manager, so they are never uniitialized.
From the specification:
A variable must be definitely assigned (ยง5.3) before its value can be
obtained. As described in the following sections, variables are either
initially assigned or initially unassigned. An initially assigned
variable has a well-defined initial value and is always considered
definitely assigned. An initially unassigned variable has no initial
value. For an initially unassigned variable to be considered
definitely assigned at a certain location, an assignment to the
variable must occur in every possible execution path leading to that
location.
For your case you have an initially unassigned variable. Thus, the variable must be set in every possible execution path. There is one possible execution path to which your variable is not defined - when userInput >= j.
This would happen if userInput is 0. Following your program manually:
The first for case will check if i != userInput. Since i = 1 this is true, thus it will continue in the for loop.
the second for case will check if j < userInput. Since j = 0 this is false, thus it will skip the for case and never set proceed
Now you have arrived to where you check proceed and it was never set. So the compiler tells you that this is not allowed.
To solve your issue, you have to decide whether to:
define a default value for proceed, for instance false and set it at declaration, i.e. bool proceed = false;.
Rewrite your logic so that you do not need the boolean, for instance like Daniel Leiszen suggests.

day of week and hour of day in a if statement c#

I want to do something if the day, and time of the day equal true in a if statement. I have the day part down, just can't figure out the time part out. Let say I wan the time to be 9AM.
Here is what I have so far
var dt_check_monday = DateTime.Now.DayOfWeek;
if (dt_check_monday == DayOfWeek.Monday && time_now = DateTime.Now.Hour==9)
{
//do something
}
I can't use this I get an error:
Operator '&&' cannot be applied to operands of type 'bool' and 'System.TimeSpan'
Thanks for any help in advance.
= is an assignment. == is the 'equals'
Your second = should be a ==
You should just do this:
if (DateTime.Now.DayOfWeek == DayOfWeek.Monday && DateTime.Now.Hour == 9)
{
}
Your code has an assignment to an undeclared variable time_now and you're doing an assignment time_now = which is what's causing it to fail.
You should also consider revising how you name your variables, dt_check_monday means absolutely nothing if the value inside it is DayOfWeek.Wednesday, consider changing it to something like dt_currentDayOfWeek but that already exists in the form of DateTime.Now.DayOfWeek which is why I dropped the variable from my example.
I think time_now is having TimeSpan datatype. So you can try this
if (dt_check_monday == DayOfWeek.Monday && time_now.Hours == 9)
{
//do something
}
If you want to keep time_now for later use, you have to encase the assignment in the if-statement with paratheses.
var dt_check_monday = DateTime.Now.DayOfWeek;
if (dt_check_monday == DayOfWeek.Monday && (time_now = DateTime.Now.Hour) == 9)
{
//do something
}

InvalidArgument error when calling LINQ First() method

So my problem is that i am getting an invalid argument error in this section of code. What it is meant to do is take a hand of cards and get the sum of their total value. Then if the value is greater than 21 it checks to see if any of the cards in the hand is an ace(or the type is == ace and it's card totalVal == 11) now my problem is the statement i have written for this will run regardless of if there is an ace in the hand or not and throws an error.
I was wondering if there is any other way i can write the statement below in order to get this to run correctly?
public int HandTotal()
{
int total = CurrentCards.Sum(n => n.Total);
**while ( total > 21 && CurrentCards.First(n => n.Type == 13 && n.Total == 11) !=null)**
{
CurrentCards.First(n => n.Type == 13).Total = 1;
total = CurrentCards.Sum(n => n.Total);
return total;
}
return total;
}
i've tried several different things including changing the != null into > 0 however that throws an invalid argument error saying that > cannot be used with this statement. Is there any other way that i can determine if CurrentCards.First(n => n.Type == 13 && n.Total == 11) is true or false?
Any help or suggestions are greatly appreciated.
Thank You
Instead of First, use Any with the predicate.
while(total > 21 && CurrentCards.Any(n => n.Type == 13 && n.Total == 11))
The First method throws an exception if there are no matching element.
You need to call FirstOrDefault, which can return null.
You should try using FirstOrDefault instead of First.First will throw an error if no elements a returned.
Also check that CurrentCards is not empty. Both First and FirstOrDefault will give an ArguementNullException if the IEnumumerable is empty.

How to check if two string are of the same length?

I want to check if two string are of the same length. I tried the following, but it doesn't work.
string passnew = "1233";
string passcnfrm = "1234";
if((passnew.Length&&passcnfrm.Length)>6 ||(passnew.Length&&passcnfrm.Length)<15)
{
// ...
}
Why does it not work? What do I need to change?
if(passnew.Length == passcnfrm.Length &&
passnew.Length > 6 && passnew.Length < 15)
{
// do stuff
}
You are missing some basic syntax lessons. What you write inside of these brackets are conditions. We have unary operators (operating on one thing), binary operators (two) and one tertiary operator (forget about that one).
You cannot construct something like your "boundary test" with those easily.
A possible way:
(passnew.Length > 6) && (passcnfrm.Length > 6)
But you aren't testing if the length is equal anyway, even if you could use a syntax like that. You seem to want to compare if both are longer than 6 chars and shorter than 15 chars. One at 7 and one at 14 would satisfy both conditions..
if(passnew.Length == passcnfrm.Length &&
(passnew.Length < 15 && passnew.Length > 6))
{
// ...
}
Checks both are same length, and either one is more than 6 and less than 15 characters long.
that would be:
if(passcnfrm.Length.Equals(passnew.Length))
{
//do stuff
}
A probably better way to do it is:
if (( passnew != null && passcnfrm != null )
( passnew == passcnfrm )
&& ( passnew.Length > 6 && passnew.Length < 15 ))
{
// do stuff
}
Hides the length check inside the equality check which you'll probably need, it isn't in your question but the variable names make it pretty clear you're doing a password change function there. I added the null check to make sure the length checks don't throw a NullReferenceException, not needed in the example because you assign both manually, but might save some trouble if you're going to convert this to a method later on.
You can use like this:
if (s.Contains(s1[i]))
or:
boolean equalsIgnoreCase(String anotherString);
or use this method:
public static int occurrence(string [] a, string a2)
{
int occ = 0;
for (int i = 0; i < a.Length;i++ )
{
if(a[i].Equals(a2))
{
occ++;
}
}
return occ;
}

Are variables shared in recursive functions

I'm trying to calculate the number of success cases within a recursive function in C#, but I'm astonished by the fact that my variable is shared between all the function calls!
[update 2]
More than strange this time. doing so
i = i + validTreesFun(tree.Nodes, newWords.ToList()) ;
resets i to 0
doing this
i = validTreesFun(tree.Nodes, newWords.ToList()) + i ;
gives some results (I'm not sure if it's correct)
[updated : the full code]
public static int validTreesFun(List<Tree<char>> nodes, List<string> words)
{
int i = 0;
if (nodes == null && (words == null || words.Count == 0 || (words.Count == 1 && words.First() == "")))
return 1;
else
if (nodes == null)
return 0;
foreach (Tree<char> tree in nodes)
{
var validWords = words.Where(w => w.ToCharArray()[0] == tree.Root)
.Select(w => w);
if (validWords.Count() == 0)
return 0;
else
{
var newWords = validWords.Select(w => join( w.ToCharArray().Skip(1).ToArray()));
i += validTreesFun(tree.Nodes, newWords.ToList());
}
}
return i;
}
when debuging the variable i take the value 1 but it resets to 0 on the next iteration!!
despite the use of
i = i + ....
What is the problem in that piece of code?
Thank you
if (validWords.Count() == 0)
return 0;
Should be
if (validWords.Count() == 0)
continue;
Also, in general, I personally think it is nicer looking to only send in one element at a time to a recursive function.
public static int validTreesFun(Tree<char> node, List<string> words)
That way you don't get the same kind of mistake like above. Finally, a minor note.
w => w.ToCharArray()[0] == tree.Root
can be written as
w => w[0] = tree.Root
No local variables are not at all shared between recursive calls, you should consider some other design problem, inside and after your foreach loop, I dont see any return statements, can you post full code.
Ok, in debugging you will always observe i's current method's value, debugging is not good in recursive functions, its little hard to understand, you will have to move your control down in Call Stack in order to actually observe value of earlier caller of current function.
I would advice you to output Trace or on log file with your level of node, that will help you actual debugging.
Please use TRACE Statement as follow..
Trace.WriteLine(string.Format("{0},{1}",tree.Name,i));
Local variables are not being shared.
What you are seeing (the reset to 0) is the value of i in the (recursively) called function validTreesFun (i gets set to 0 at the start of the function).
Just looking at your code, I think a possible bug might be in someTestHere - if that is never true, then i will stay 0 in the outer scope. Otherwise it should increment by 1 for each true test.
When you are in debug mode, you indeed see that the i is reseted for the call but remain to the wanted value for the caller. Eg , the stack :
validTreesFun --i = 0 for this one
validTreesFun --i = x for this one, but if you do not go trow the calling stack, you will see 0, which is the good value for the top of the stack

Categories

Resources