Any way to further reduce the number of lines of code? - c#

I'm looking for ways to reduce the number of lines of code for this function. Any help is appreciated!
private bool CanSubmitPackage ( object obj )
{
// ---- Checks if the package contains any files to be submitted ----
if ( _selectedWorkspace.Package.Files != null )
{
if ( _selectedWorkspace.Package.Files.Count > 0 )
if ( _selectedWorkspace.Package.Platform != null || _selectedWorkspace.Package.Platform != "" )
if ( _selectedWorkspace.Package.PackagePath != null || _selectedWorkspace.Package.PackagePath != "" )
if ( _selectedWorkspace.Package.PackageSize != null || _selectedWorkspace.Package.PackageSize != "" )
if ( _selectedWorkspace.Package.SubmittedBy != null || _selectedWorkspace.Package.SubmittedBy != "" )
return true;
else
return false;
else
return false;
else
return false;
else
return false;
else
return false;
}
else
return false;
}

return ( _selectedWorkspace.Package.Files?.Count > 0
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.Platform)
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.PackagePath)
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.PackageSize)
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.SubmittedBy));

You can make it shorter and readable by using && operator and string.IsNullOrEmpty method:
return ( _selectedWorkspace.Package.Files != null
&& _selectedWorkspace.Package.Files.Count > 0
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.Platform)
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.PackagePath)
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.PackageSize)
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.SubmittedBy));
If you're using c#6+, then you can go further (just a little bit) and use Expression Bodied method:
private bool CanSubmitPackage () => //I'm not sure about object obj argument
( _selectedWorkspace.Package.Files != null
&& _selectedWorkspace.Package.Files.Count > 0
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.Platform)
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.PackagePath)
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.PackageSize)
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.SubmittedBy));
If you are going after making your code text shorted, you can declare a short named variable and use that instead of _selectedWorkspace.Package:
var p = _selectedWorkspace.Package;
return (p.Files?.Count > 0
&& !string.IsNullOrEmpty(p.Platform)
&& !string.IsNullOrEmpty(p.PackagePath)
&& !string.IsNullOrEmpty(p.PackageSize)
&& !string.IsNullOrEmpty(p.SubmittedBy));;

This is one way to do it
Update
return ( _selectedWorkspace != null
&& _selectedWorkspace.Package != null
&& _selectedWorkspace.Package.Files != null
&& _selectedWorkspace.Package.Files.Count > 0
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.Platform)
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.PackagePath)
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.PackageSize)
&& !string.IsNullOrEmpty(_selectedWorkspace.Package.SubmittedBy));
Old Ans
return ( _selectedWorkspace.Package.Files != null
&& _selectedWorkspace.Package.Files.Count > 0
&& ( _selectedWorkspace.Package.Platform != null || _selectedWorkspace.Package.Platform != "" )
&& ( _selectedWorkspace.Package.PackagePath != null || _selectedWorkspace.Package.PackagePath != "" )
&& ( _selectedWorkspace.Package.PackageSize != null || _selectedWorkspace.Package.PackageSize != "" )
&& ( _selectedWorkspace.Package.SubmittedBy != null || _selectedWorkspace.Package.SubmittedBy != "" ));

This is another way to do it
private bool CanSubmitPackage(object obj)
{
// ---- Checks if the package contains any files to be submitted ----
if (_selectedWorkspace.Package.Files == null) return false;
if (_selectedWorkspace.Package.Files.Count <= 0) return false;
if (_selectedWorkspace.Package.Platform == null && _selectedWorkspace.Package.Platform == "") return false;
if (_selectedWorkspace.Package.PackagePath == null && _selectedWorkspace.Package.PackagePath == "") return false;
if (_selectedWorkspace.Package.PackageSize != _selectedWorkspace.Package.PackageSize != "")
return _selectedWorkspace.Package.SubmittedBy != null || _selectedWorkspace.Package.SubmittedBy != "";
return false;
}

I would prefer #xneg's answer (https://stackoverflow.com/a/53096740/10588170), however, you could also drop all 'else' Statements and replace them with a single return statement after the 'if'-block.
Make sure to use string.IsNullOrEmpty(_str) in future, or you have to use && instead of ||, otherwise you will get an Exception because you are checking if _str is empty if it is null and if it is not null, you are not checking the content of _str at all. I am pretty sure that that's not what you wanna do.

I would maybe split the conditions, for example:
public bool HasFile
{
get { return _selectedWorkspace.Package.Files != null && _selectedWorkspace.Package.Files.Count > 0; }
}
public bool HasPlatform
{
get { return !string.IsNullOrEmpty(_selectedWorkspace.Package.Platform); }
}
// Do that for all conditions
And then you can write your final if like this:
bool result = HasFile && HasPlatform && …

If you wanted to keep it largely the same, as the return for all of your IF statements failing is false, you only need to include it once. If any of your current checks fail, it won't be able to execute "return true", so you can just have one final return statement like this:
private bool CanSubmitPackage ( object obj )
{
// ---- Checks if the package contains any files to be submitted ----
if ( _selectedWorkspace.Package.Files != null )
if ( _selectedWorkspace.Package.Files.Count > 0 )
if ( _selectedWorkspace.Package.Platform != null || _selectedWorkspace.Package.Platform != "" )
if ( _selectedWorkspace.Package.PackagePath != null || _selectedWorkspace.Package.PackagePath != "" )
if ( _selectedWorkspace.Package.PackageSize != null || _selectedWorkspace.Package.PackageSize != "" )
if ( _selectedWorkspace.Package.SubmittedBy != null || _selectedWorkspace.Package.SubmittedBy != "" )
return true;
// One of the above checks failed, that's why we're running this line
return false;
}
I also prefer #xneg, #SeM, or #Mihir Dave's approach (as they're all basically the same answer), but it does come down to what you find most comfortable / readable. I would definitely use the method String.IsNullOrEmpty() to simplify your if statements however.
Additionally, what the ? does in xneg's answer: _selectedWorkspace.Package.Files?.Count is say "If Files is not null, retrieve Files.Count, otherwise return null. Then in C# a statement like, null > 0 always returns false.

Related

convert lambda expression to function

I wish to debug lambda expression but its not possible as it sets breakpoint on whole expression.
Here is my lambda expression
public bool CanRevert => _objectEntity != null && !(_objectEntity != null &&
ObjectDescription == _objectEntity.DTO.Description &&
ObjectInstance == _objectEntity.DTO.ObjectInstance.ToString() &&
Name == _objectEntity.DTO.ObjectName &&
(SelectedDevice != null && SelectedDevice.Id == _objectEntity.DTO.DeviceID) &&
(_objectEntity.DTO.ObjectCategoryID.HasValue ? (SelectedObjectCategory != null && SelectedObjectCategory.Id == _objectEntity.DTO.ObjectCategoryID.Value) : SelectedObjectCategory == null) &&
(_objectEntity.DTO.ObjectTypeID.HasValue ? (SelectedObjectType != null && SelectedObjectType.Id == _objectEntity.DTO.ObjectTypeID.Value) : SelectedObjectType == null));
I wanted to put breakpoint inside selectedDevice but i cant. Hence i tried to write it like
public bool CanRevert()
{
if (SelectedDevice != null)
{
var s = SelectedDevice.Id == _objectEntity.DTO.DeviceID;
}
var d = _objectEntity != null && !(_objectEntity != null &&
ObjectDescription == _objectEntity.DTO.Description &&
ObjectInstance == _objectEntity.DTO.ObjectInstance.ToString() &&
Name == _objectEntity.DTO.ObjectName &&
(SelectedDevice != null && SelectedDevice.Id == _objectEntity.DTO.DeviceID) &&
(_objectEntity.DTO.ObjectCategoryID.HasValue ? (SelectedObjectCategory != null && SelectedObjectCategory.Id == _objectEntity.DTO.ObjectCategoryID.Value) : SelectedObjectCategory == null) &&
(_objectEntity.DTO.ObjectTypeID.HasValue ? (SelectedObjectType != null && SelectedObjectType.Id == _objectEntity.DTO.ObjectTypeID.Value) : SelectedObjectType == null));
return d;
}
Is it right way to convert it? I ask because i am starting to get somewhere in application that Binding to this method is not supported
You can achieve the same result like this.
Put a breakpoint in your expression.
Start Debugging (F5)
Highlight (SelectedDevice != null && SelectedDevice.Id == _objectEntity.DTO.DeviceID) in your expression
Right-click and select Add Watch
Now you have its calculated value in the Watch window. (Usually pops up at the bottom)
You can use Quick Watch (Shift+F9) if you want its value once.

How to break if-else-if using C#

How do I break if-else-if.....Why its not working? its just checking all the conditions instead of performing the tasks. following is my code. I have checked it through breakpoints its moving to all conditions why it doesn't get stop after meeting the correct condition. even it is not going into the if activity it just read all the conditions and do nothing at the end.
private void ShowHash()
{
inpic = pb_selected.Image;
Bitmap image = new Bitmap(inpic);
byte[] imgBytes = new byte[0];
imgBytes = (byte[])converter.ConvertTo(image, imgBytes.GetType());
string hash = ComputeHashCode(imgBytes);
txt_selectedText.Text = hash;
GetHash();
}
private void GetHash()
{
if (txt_sel1.Text == null && (txt_sel2.Text == null || txt_sel3.Text == null || txt_sel4.Text == null || txt_sel5.Text == null ))
{
txt_sel1.Text = txt_selectedText.Text;
return;
}
else if (txt_sel1.Text != null && (txt_sel2.Text == null || txt_sel3.Text == null || txt_sel4.Text == null || txt_sel5.Text == null))
{
txt_sel2.Text = txt_selectedText.Text;
return;
}
else if (txt_sel2.Text != null && (txt_sel3.Text == null || txt_sel4.Text == null || txt_sel5.Text == null))
{
txt_sel3.Text = txt_selectedText.Text;
return;
}
else if (txt_sel3.Text != null && (txt_sel4.Text == null || txt_sel5.Text == null))
{
txt_sel4.Text = txt_selectedText.Text;
return;
}
else if (txt_sel4.Text != null && (txt_sel5.Text == null))
{
txt_sel5.Text = txt_selectedText.Text;
return;
}
}
I strongly suspect the problem is that the Text property is never null for any of txt_sel*. Assuming these are text boxes in a UI, it's much more likely that if there's no text in the text box, the Text property will return "" instead of null. That's the way most UI frameworks handle empty controls.
I would also suggest extracting the conditions into local variables first:
bool hasSel1 = txt_sel1.Text != "";
bool hasSel2 = txt_sel2.Text != "";
bool hasSel3 = txt_sel3.Text != "";
bool hasSel4 = txt_sel4.Text != "";
bool hasSel5 = txt_sel5.Text != "";
if (!hasSel1 && (!hasSel2 || !hasSel3 || !hasSel4 || !hasSel5)
{
...
}
And ideally, give your controls more meaningful names - a collection of variables with the same prefix but then a numeric suffix is very rarely a good idea, in terms of readability.
Reason:
If there is nothing in those textboxes, textbox.Text will return an empty string ("") not null.
Solution:
Check against "" not null:
private void GetHash()
{
if (txt_sel1.Text == "" && (txt_sel2.Text == "" || txt_sel3.Text == "" || txt_sel4.Text == "" || txt_sel5.Text == ""))
{
txt_sel1.Text = txt_selectedText.Text;
return;
}
else if (txt_sel1.Text != "" && (txt_sel2.Text == "" || txt_sel3.Text == "" || txt_sel4.Text == "" || txt_sel5.Text == ""))
{
txt_sel2.Text = txt_selectedText.Text;
return;
}
....
....
EDIT: You don't have to do ==true for boolean variables. If statement checks it against true by default. Use ! to check against false:
if (hasValue1 && (hasValue2 || hasValue3 || hasValue4 || hasValue5))
{
txt_sel1.Text = txt_selectedText.Text;
return;
}
else if (hasValue2 && (!hasValue1 ||hasValue3 || hasValue4 || hasValue5))
{
txt_sel2.Text = txt_selectedText.Text;
return;
}
else if (hasValue3 && (!hasValue1 || hasValue2 || hasValue4 || hasValue5))
{
txt_sel3.Text = txt_selectedText.Text;
return;
}
....
....
I think for string better to use inbuild null and whitespace check function:
bool hasValue1 = string.IsNullOrWhiteSpace(txt_sel1.Text);
bool hasValue2= string.IsNullOrWhiteSpace(txt_sel2.Text);
bool hasValue3= string.IsNullOrWhiteSpace(txt_sel3.Text);
bool hasValue4= string.IsNullOrWhiteSpace((txt_sel4.Text);
bool hasValue5 = string.IsNullOrWhiteSpace(txt_sel5.Text);
And then define if condition on these bool. This case can handle unexpected null or white space values.
That is bacause it probably doesn't find any of those conditions true.
If it would find a true condition it would execute that if block and won't event check the others.
To add to what others have said, you should really have a final else statement in there to catch issues such as this:
else
{
throw new InvalidOperationException("My If Statement is Broken");
}
Thanks to you all! My problem is solved by changing the conditions and your suggested alteration, following is the code may be helped some beginner like me.
private void GetHash()
{
bool hasValue1 = string.IsNullOrWhiteSpace(txt_sel1.Text);
bool hasValue2 = string.IsNullOrWhiteSpace(txt_sel2.Text);
bool hasValue3 = string.IsNullOrWhiteSpace(txt_sel3.Text);
bool hasValue4 = string.IsNullOrWhiteSpace(txt_sel4.Text);
bool hasValue5 = string.IsNullOrWhiteSpace(txt_sel5.Text);
if (hasValue1 && (hasValue2 || hasValue3 || hasValue4 || hasValue5))
{
txt_sel1.Text = txt_selectedText.Text;
return;
}
else if (hasValue2 && (!hasValue1 ||hasValue3 || hasValue4 || hasValue5 ))
{
txt_sel2.Text = txt_selectedText.Text;
return;
}
else if (hasValue3 && (!hasValue1 || !hasValue2 || hasValue4 || hasValue5 ))
{
txt_sel3.Text = txt_selectedText.Text;
return;
}
else if (hasValue4 && (!hasValue1 || !hasValue2 || !hasValue3 || hasValue5 ))
{
txt_sel4.Text = txt_selectedText.Text;
return;
}
else if (hasValue5 && (!hasValue1 || !hasValue2 || !hasValue3 || !hasValue4 ))
{
txt_sel5.Text = txt_selectedText.Text;
return;
}
else
{
CompareHash();
}
}

evaluation of conditions in an if statement

Suppose I have this if statement:
foreach (MyModel m in SomeList)
{
if (m.pID != SomeValue && (m.xID != 0 && SomeFunction(m.xID) == false)
{
return false;
}
}
I only want SomeFunction(m.xID) == false to evaluate if m.xID != 0 so if m.xID == 0 then don't evaluate SomeFunction
For the moment, I have this if statement broken down into 2 statements and I'm looking to see how I can combine these into just one while preserving the logic. This is the original:
foreach (MyModel m in SomeList)
{
if (m.xID != 0 && SomeFunction(m.xID) == false)
{
return false;
}
if (m.pID != SomeValue)
{
return false;
}
}
If that is all your loop is doing then I would be inclined to remove the loop entirely.
Also, instead of comparing something to false, just use the ! operator.
if (SomeList.Any(MyModel m=>m.xID != 0 && !SomeFunction(m.xID) || m.pID != SomeValue))
return false;
you are looking for this || Operator (C# Reference)
if ((m.xID != 0 && SomeFunction(m.xID) == false) || (m.pID != SomeValue))
{
return false;
}

Due to LINQ Retrieving of Record data's i have this error: NullReferenceException was unhandled by user code

private void getUserLoginDepartment(string AccessID, string UserPROFid)
{
try
{
DBWPAccountRecordsDataContext DBACCOUNT = new DBWPAccountRecordsDataContext();
var query = (from i in DBACCOUNT.WP_UserAccessPorts
join
z in DBACCOUNT.WP_Departments on i.AccessPortID equals z.Dept_ID
where i.AccessPortID == AccessID && i.ProfileUser_ID == UserPROFid
select new
{
PORT1 = i.AccessPoint1,
PORT2 = i.AccessPoint2,
PORT3 = i.AccessPoint3,
PORT4 = i.AccessPoint4,
DEPT = z.Dept_DESC,
DEPTPORT = z.Dept_PortNo
}).FirstOrDefault();
if (query.PORT1.ToString() != null || query.PORT1.ToString() != string.Empty)
{ Session["Port1"] = query.PORT1; }
else { Session["Port1"] = ""; }
if (query.PORT2.ToString() != null || query.PORT2.ToString() != string.Empty)
{ Session["Port2"] = query.PORT2; }
else { Session["Port2"] = ""; }
if (query.PORT3.ToString() != null || query.PORT3.ToString() != string.Empty)
{ Session["Port3"] = query.PORT3; }
else { Session["Port3"] = ""; }
if (query.PORT4.ToString() != null || query.PORT4.ToString() != string.Empty)
{ Session["Port4"] = query.PORT4; }
else { Session["Port4"] = ""; }
}
finally
{
}
}
The Error occures when i reach break point 1st IF Statement the record on my database shows that its not empty which its value is "WebAdmin" but then suppost to be it should pick it up and store it to the Session["PORT1"] that i have made is there something i missed or i'm doing it wrong on my linq Query. NOTE:*This is an ASP.NET C# Application
EDIT 10/2/2013 0420PM:
It's still an Error After using that method sir.
1) you should check query for null when you use FirstOrDefault
2) you need to check each PORTX for null
3) use string.IsNullOrEmpty( ) to check if the string of PORTX is null
var query = ( ... ).FirstOrDefault( );
if( query != null )
{
if( query.PORT1 != null && !string.IsNullOrEmpty( query.PORT1.ToString( ) ) )
{
}
else { ... }
}
You have to check query.PORT1 for null before calling ToString on it, you can use String.IsNullOrEmpty to check both conditions. Before checking query.PORT1 you need to check if query is null or not. You also need to use && instead of or operator as || will cause the right side of or operator to be evaluated if left is false and on right side calling ToString on null will again through exception.
if (query != null && query.PORT1 != null && query.PORT1.ToString() != string.Empty)
{ Session["Port1"] = query.PORT1; }
Using IsNullOrEmpty
if(query != null && !String.IsNullOrEmpty(query.PORT1))
{
Session["Port1"] = query.PORT1;
}

LINQ List gives null exception in where Clause

var q = from p in query
where
((criterias.birthday == p.BirthDay|| criterias.birthday == null))
&& ((criterias.marriageDate == null || criterias.marriageDate == p.MarriageDate))
&& ((criterias.gender == p.Gender) || (criterias.gender == null))
&& ((criterias.nationalities.Contains(p.Nationality)) || (criterias.nationalities == null))
criterias isa class where i store my search criterias. nationalities is a string list. the problem occurs when i have no items in string. the query throws null reference exception. the query doesnt accept null value in nationalities. how can i fix this?
Reverse the order so that the null check comes before the query: as you're using ||, the second part of the expression is only evaluated when the first part evaluates to false:
&& ((criterias.nationalities == null) ||
(criterias.nationalities.Contains(p.Nationality)))
Look at these 2:
((criterias.birthday == p.BirthDay|| criterias.birthday == null))
&& ((criterias.marriageDate == null || criterias.marriageDate == p.MarriageDate))
I don't think marriageDate will give you problems but birthday uses the wrong order.
In this case you need the 'short-circuit evaluation' property of ||, change it to:
(criterias.birthday == null || criterias.birthday == p.BirthDay)
&& (criterias.marriageDate == null || criterias.marriageDate == p.MarriageDate)
Try swapping the order of the nationalties checks. It should short-circuit on the null check before it tries to evaluate the Contains.
((criterias.nationalities == null) || (criterias.nationalities.Contains(p.Nationality)))
Turn this statement around:
(criterias.nationalities.Contains(p.Nationality)) || (criterias.nationalities == null)
so that it reads
(criterias.nationalities == null) || (criterias.nationalities.Contains(p.Nationality))
If the first operand evaluates to true, the second one will be skipped.
Try first check for null then (if it is not null) check for contains:
var q = from p in query
where
((criterias.birthday == p.BirthDay|| criterias.birthday == null))
&& ((criterias.marriageDate == null || criterias.marriageDate == p.MarriageDate))
&& ((criterias.gender == p.Gender) || (criterias.gender == null))
&& ((criterias.nationalities == null) || (criterias.nationalities.Contains(p.Nationality))

Categories