C#: Use of unassigned local variable, using a foreach and if - c#

I have this following code:
I get the error, "Use of un-Assigned Local variable"
I'm sure this is dead simple, but im baffled..
public string return_Result(String[,] RssData, int marketId)
{
string result;
foreach (var item in RssData)
{
if (item.ToString() == marketId.ToString())
{
result = item.ToString();
}
else
{
result = "";
}
}
return result;
}

Initialize result when you declare it. If the collection is empty neither of the branches of the if statement will ever be taken and result will never be assigned before it is returned.
public string return_Result(String[,] RssData, int marketId)
{
string result = "";
foreach (var item in RssData)
{
if (item.ToString() == marketId.ToString())
{
result = item.ToString();
}
}
return result;
}

If there are no items in RssData, then result will have never been set, and thus invalid.
Either initialize result (e.g., string result = null;) or consider that in your design by checking for emptiness, and setting or returning a failure state in that scenario.

That is because the compiler can't know that there always are any items in RssData. If it would be empty, the code in the loop would never be executed, and the variable would never be assigned.
Just set the variable to null when you create it, so that it always has a value:
string result = null;

If RssData has zero items, the loop will not run, leaving result undefined. You need to initialize it to something (e.g. string result = "";) to avoid this error.

Change your line from
string result;
To
string result = string.Empty; // or null depending on what you wish to return (read further)
The compiler is just saying "Hey, you are using result and it has not been assigned yet!". This even ocurrs when you are assigning it for the first time, if you're not doing so in the initial instantiation.
You will also want to consider how you need to handle your code if you return an empty string, due to your array argument being passed in empty. You could choose to return an empty string, or a null value. This is just a behaviorial decision.

This can happen for all variable types as well.
For collections and objects, initialize using new.
eg. List<string> result = new List<string>();

Related

c# Value still null after assigning a value

i don't know what i'm doing wrong, i'm working on an existing application and i'm creating a unit test for this method.
on the Test Method, i mocked the view and assigned a value on the item
_fakeView.Setup(x => x.Bag.Amount).Returns((decimal)300.32);
(Note that the Amount is string)
and i'm passing the view object to the presenter and initialized
_presenter = new Presenter(_fakeView.Object);
_presenter.InitializeForm();
and on the existing code for initialize, they have a line of code to reassign the values like this:
this._view.Amount = this._view.Bag.Amount.ToString();
when this line run, the this._view.Amount is still null even if this._view.Bag.Amount.ToString() has value.
i even tried setting it directly
this._view.Amount = "asdfgsdf"; but still null
please help
Just because you assign a value something, doesn't mean it can't be null. this._view.Bag.Amount.ToString() has to be returning null.
This means, either this._view is null, this._view.Bag is null, or this._view.Bag.Amount is null, or ToString() is failing somehow. You'll have to check the values and find out where the null is coming from.
Also, if Amount is string why are you using ToString()?
Edit: It is possible that the code for Amount is something like this:
// Get works as expected but set does literally nothing to change the backing field
private string amount = null;
public string Amount
{
get => amount;
set
{
// Do literally nothing
}
}
Or:
// Get will always return null, but set works as expected
prviate string amount;
public string Amount
{
get => null;
set => amount == value;
}
In both examples, Amount will always return null if you're trying to use only the set/get.
Is there a SetAmount(string amount) method you could call?
i found what i'm missing..
_fakeView.SetupAllProperties();
i added this
_fakeView.SetupAllProperties();
before
_fakeView.Setup(x => x.Bag.Amount).Returns((decimal)300.32);

Why compiler treats System.Object as null when its set to False

I wrote a generic method to retrieve single values from database (MSSQL Server).I encountered into a case that I need to get a Boolean value from DB.
As you can see in the code below, a Object local field (IsExist) gets the result.
When the value in DB is False GenericScalar() method return False (as it should)
and the condition: if (IsExist == null) in GetWanLineDisconnectionData() is true and the return block is executing, even though IsExist is False and not null.
Why is that?
How can I overcome this problem?
private void GetWanLineDisconnectionData()
{
string q = "SELECT WanLineDiscconection FROM AdditionalProjectsData WHERE SpCall= " + "'" + spCall + "'";
object IsExist = Orange.ProjectManagment.DAL.Database.GenericScalar<object>(q);
if (IsExist == null) {
return;
}
if (bool.Parse(IsExist) == true) {
RadWanDiscYes.Checked = true;
} else {
RadWanDiscNo.Checked = true;
}
}
Database method:
public static T GenericScalar<T>(string query)
{
OleDbConnection connection = new OleDbConnection(sqlConnString);
connection.Open();
OleDbCommand cmd = new OleDbCommand(query, connection);
try
{
var result = cmd.ExecuteScalar();
if (result == null)
{
return default(T);
}
else
{
return (T)result;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
CloseConnection(ref connection);
}
}
EDIT:
maybe a few screen shoots will better demonstrate it:
(note that: GetWanLineDisconnectionData() is written in VB.NET and GenericScalar() is written in C# on a different project in the solution):
in the beginning IsExist is nothing (null).
the query finds one row and the value of the bool column WanLineDiscconection is false and IsExist is set to false as it should be.
here is the problem, the program enters the if block and IsExist is not nothing (null).
The variable foo in object foo = false is definitely not null, so the premise in your title is incorrect.
ExecuteScalar() returns null when there are no rows. In that case, the method GenericScalar() return default(T), which for object will be null.
How to solve this depends on what your data looks like. You probably want to represent the result in a nullable int, or int? instead of object:
var exists = Orange.ProjectManagment.DAL.Database.GenericScalar<int?>(q);
RadWanDiscYes.Checked = exists.GetValueOrDefault() > 0;
See How does GetValueOrDefault work?, What is the default value of the nullable type "int?" (including question mark)?.
Aside from that: you generally also don't want to write handy wrappers around database queries, because you're reinventing the wheel poorly, opening up your application to SQL injection. That being said, there's a lot more going wrong in that method, including but not limited to not disposing your database connection and rethrowing exceptions without their stacktrace.
You´re mixing compile-time and runtime information. Whilst GenericScalar<object>(q) is an information that exists at compile-time the type returned from ExecuteScalar at compile-time is just object. You expect it to be of type boolean, which might or might not be true for your specific case. However this is not relevant to the compiler.
In short that means that T actually is object, not whatever you expect it to be from your database. And as CodeCaster allready mentioned the default-value for object is just null.
Si I´d suggest to use GenericScalar<bool> instead of GenericScalar<object> because you seem to know what your query actually returns - in your case a bool. Then default(T) evaluates to false, not to null.

using a method invoker in an if statement

what i am trying to do is check whether an item in a list box is selected.
The method is being run on a separate thread so i would need to use a method invoker i believe.
string list = "";
lbxList.Invoke(new MethodInvoker(delegate { list = lbxList.SelectedItem.ToString(); }));
if (list != null)
{
//do something
}
this code will blow up if the selected item is null because the string list wont hold it, so i would need a way to combine the top 2 lines into an if statement checking for null.
Thanks
This should do:
string list = "";
lbxList.Invoke(new MethodInvoker(delegate
{
if (lbxList.SelectedItem != null)
list = lbxList.SelectedItem.ToString();
}));
//do something
Just place the if-statement inside the anonymous method.
Note that .ToString is highly unlikely to ever return null for anything, the documentation of object.ToString states that overriding types should implement the method to return a meaningful value. Since we already know that .SelectedItem is not null, checking for null is not really necessary. You can leave it in if you really want, but if you're afraid that .ToString should return null, I would instead change the code to this:
string list = "";
lbxList.Invoke(new MethodInvoker(delegate
{
if (lbxList.SelectedItem != null)
list = lbxList.SelectedItem.ToString() ?? string.Empty;
}));
//do something

Linq syntax error in ASP MVC controller method

I have a Linq query I need to use in my Index method in the page's controller, however I am getting the following error on the "select new" portion of the code:
Error
Cannot implicitly convert type 'System.Linq.IQueryable<AnonymousType#1>' to 'string'
Action method
public ActionResult Index(string query)
{
var agentProductTraining = "";
if (String.IsNullOrEmpty(query))
{
BlankIndex();
}
else
{
agentProductTraining = from course in db.Course
where
course.CourseDescription.Contains(query)
select new
{
course.CourseCode,
course.CourseDescription,
course.Partner,
course.Status,
course.LastChangeDate,
course.LastChangeOperator
};
}
return View(agentProductTraining.ToList());
}
As the error clearly states, you cannot assign the result of a LINQ query (IQueryable<T>) to a variable of type string.
You should declare the variable in that line:
var agentProductTraining = select ...
You've initialized the variable as a string, so the compiler makes the variable a string type (since you've user the var keyword), but then tried to assign a collection of anonymous types to it.
You can declare it as an object instead or var:
object agentProductTraining; // can safely be overwritten
Also I assume you mean:
return BlankIndex();
in the if block. Otherwise it will fall through to
return View(agentProductTraining.ToList());
where agentProductTraining is going to be null
Of course if you use return BlankIndex in the if block you can simplify the whole thing:
if (String.IsNullOrEmpty(query))
{
return BlankIndex();
}
// don't need an `else` here since the if will return to the caller
var agentProductTraining = from course in db.Course
where
course.CourseDescription.Contains(query)
select new
{
course.CourseCode,
course.CourseDescription,
course.Partner,
course.Status,
course.LastChangeDate,
course.LastChangeOperator
};
return View(agentProductTraining.ToList());

Null Exception handling in foreach loop

I am having the list X with some string and null value . I am iterating the foreach loop to bind the value to the textbox. If I get any null values in my list X the foreach loop get terminated and getting the null exception how to handle it.
I am checking the condition inside the foreach loop, but I think it's not correct logically.
SPList _listObj = web.Lists[new Guid(listID)];
SPListItem item = _listObj.GetItemById(Convert.ToInt32(itemID));
foreach (SPField field in _listObj.Fields)
{
if (field.Title != Null)
{ //do some code}}
Try below code:
foreach(var x in Lists.Where(x => x.fiels != null))
{
}
Why don't you use it like this with null-coalescing operator
foreach (var item in feeList ?? new List<FeeBusiness>())
{
// your code
}
The ?? operator is called the null-coalescing operator. It returns the left-hand operand if the operand is not null; otherwise it returns the right hand operand.
That code looks pretty suspicious to me.
Firstly, do you really have a list of lists? If so, I'd imagine you have to iterate over each element in the inner list as well:
foreach(List list in Lists)
{
foreach (var x in list)
{
if (x.fields != null)
// blah
else
// blah
}
}
Secondly, are you sure that the Lists variable doesn't contain any nulls? Possibly it's actually x which is null, and that's the cause of your Null Reference Exception:
foreach(List x in Lists)
{
if (x != null && x.fields != null)
// blah
else
// blah
}
The code provided is not correct. I suppose you want to check X for Null in foreach loop. If this is logically correct or not, instead only you may know as logic goes beyond the code provided and depends on where you actually use it.
I personally don't find nothing bad to check for nulls in foreach loop.
You also, for example, can use Linq to query first for Null values and after Non Null values. The matter of design choice.
Regards.
List x in Lists? You probably mean to do:
foreach(string x in listvar){
if(x != null)
// do something
}
And are the strings actually null or just empty? That is a difference.
foreach(string x in listvar){
if(x != "")
// do something
}
I suspect that the problem is in your incorrect implementation of the foreach loop which causes to pop null errors as the objects inside the loop do not exist.
string delimitedvalues = null;//"11,22,33";
foreach(var str in (delimitedvalues?? string.Empty).split(','))
{
string testvalue = "Test Value" + str;
}
Hope the above construct is useful!
You have to make sure that your object you are getting doesn't come back as null (your list, _listObj) before you ever iterate its fields. Even if you are certain the GUID you are passing in matches the list you are trying to get, you should be checking that object for being null, and checking for the number of fields, and if you get an item for the ID you are passing in:
SPList _listObj = web.Lists[new Guid(listID)];
if (_listObj != null) // do we have a list object?
{
if (_listObj.Fields.Count > 0) // do we have list columns on the list?
{
SPListItem item = _listObj.GetItemById(Convert.ToInt32(itemID));
if (item != null) // did our item ID get a hit?
{
foreach (SPField field in _listObj.Fields)
{
if (field.Title != null) // need lower case null, here
{
//do some code
}
}
}
}
}

Categories