C# How to make this code easier and shorter - c#

I am beginner and i wanna ask how to make this code more simple and shorter
Thanks for all replies
public static bool SelectedSingleAcc(SpecialForms.AccountManager am)
{
//checkbox1
if (am.selectedCB1.Checked == true
&& am.selectedCB2.Checked == false
&& am.selectedCB3.Checked == false
&& am.selectedCB4.Checked == false
&& am.selectedCB5.Checked == false
&& am.selectedCB6.Checked == false
&& am.selectedCB7.Checked == false
&& am.selectedCB8.Checked == false) return true;
//checkbox2
if (am.selectedCB1.Checked == false
&& am.selectedCB2.Checked == true
&& am.selectedCB3.Checked == false
&& am.selectedCB4.Checked == false
&& am.selectedCB5.Checked == false
&& am.selectedCB6.Checked == false
&& am.selectedCB7.Checked == false
&& am.selectedCB8.Checked == false) return true;
//checkbox3
if (am.selectedCB1.Checked == false
&& am.selectedCB2.Checked == false
&& am.selectedCB3.Checked == true
&& am.selectedCB4.Checked == false
&& am.selectedCB5.Checked == false
&& am.selectedCB6.Checked == false
&& am.selectedCB7.Checked == false
&& am.selectedCB8.Checked == false) return true;
//checkbox4
if (am.selectedCB1.Checked == false
&& am.selectedCB2.Checked == false
&& am.selectedCB3.Checked == false
&& am.selectedCB4.Checked == true
&& am.selectedCB5.Checked == false
&& am.selectedCB6.Checked == false
&& am.selectedCB7.Checked == false
&& am.selectedCB8.Checked == false) return true;
//checkbox5
if (am.selectedCB1.Checked == false
&& am.selectedCB2.Checked == false
&& am.selectedCB3.Checked == false
&& am.selectedCB4.Checked == false
&& am.selectedCB5.Checked == true
&& am.selectedCB6.Checked == false
&& am.selectedCB7.Checked == false
&& am.selectedCB8.Checked == false) return true;
//checkbox6
if (am.selectedCB1.Checked == false
&& am.selectedCB2.Checked == false
&& am.selectedCB3.Checked == false
&& am.selectedCB4.Checked == false
&& am.selectedCB5.Checked == false
&& am.selectedCB6.Checked == true
&& am.selectedCB7.Checked == false
&& am.selectedCB8.Checked == false) return true;
//checkbox7
if (am.selectedCB1.Checked == false
&& am.selectedCB2.Checked == false
&& am.selectedCB3.Checked == false
&& am.selectedCB4.Checked == false
&& am.selectedCB5.Checked == false
&& am.selectedCB6.Checked == false
&& am.selectedCB7.Checked == true
&& am.selectedCB8.Checked == false) return true;
//checkbox8
if (am.selectedCB1.Checked == false
&& am.selectedCB2.Checked == false
&& am.selectedCB3.Checked == false
&& am.selectedCB4.Checked == false
&& am.selectedCB5.Checked == false
&& am.selectedCB6.Checked == false
&& am.selectedCB7.Checked == false
&& am.selectedCB8.Checked == true) return true;
return false;
}

// get all values into an array for easier handling:
values = new[]
{
am.selectedCB1.Checked,
am.selectedCB2.Checked,
am.selectedCB3.Checked,
am.selectedCB4.Checked,
am.selectedCB5.Checked,
am.selectedCB6.Checked,
am.selectedCB7.Checked,
am.selectedCB8.Checked,
};
// find out if exactly one is true
return values.Count(val => val == true) == 1;
That said... the correct UI decision would be to use radio buttons instead of check boxes. They already implement this logic for you. And any time you catch yourself numbering your variables, you should think hard about why this should not be an array instead of many single variables.

public static bool SelectedSingleAcc(SpecialForms.AccountManager am)
{
int checkedNumbers = 0;
if (am.selectedCB1.Checked) checkedNumbers++;
if (am.selectedCB2.Checked) checkedNumbers++;
if (am.selectedCB3.Checked) checkedNumbers++;
if (am.selectedCB4.Checked) checkedNumbers++;
if (am.selectedCB5.Checked) checkedNumbers++;
if (am.selectedCB6.Checked) checkedNumbers++;
if (am.selectedCB7.Checked) checkedNumbers++;
if (am.selectedCB9.Checked) checkedNumbers++;
if (checkedNumbers == 1) //only one checkbox selected, we think the result is true
return true;
return false;
}

So it looks like you're checking that at most one checkbox is checked the n return true, otherwise return false
Because, in order to even appear on a form, controls have to be added to a Controls collection we can search through it (using LINQ) looking for controls that match a criteria. In this case we'll look through the controls for any that are checkboxes, and counting those whose name starts with "selectedCB" and whose state is checked. We compare the count to 1, and if there is only 1 then the result is true, if there are 0 or 2+ the result is false:
return p.Controls
.OfType<Checkbox>()
.Count(c => c.Name.StartsWith("selectedCB") && c.Checked) == 1;
p is the name of the panel/group box that holds the checkboxes.
If they are straight on the form use this (or the name of the form variable, if this code isn't part of the form that holds the boxes).
If there are no other checkboxes in the panel/on the form you can remove the c.Name.StartsWith.... The check on name is purely there to stop e.g. your isActiveCheckbox being checked and hence also polluting the count
If there are other checkboxes also having a name that starts with "selectedCB", it would be simplest to rename them so that only these 8 checkboxes have a name starting with "selectedCB", or put them in their own panel but add a comment if you want a more refined logic eg a Regex that insists the name be selectedCB[1-8]

It looks like the rule you're implementing is an exclusive OR condition between then status of the 8 checkboxes.
IN that case using C#'s XOR operator ^ would probably yield a contender for the shortest solution e.g.
public static bool SelectedSingleAcc(SpecialForms.AccountManager am)
{
return am.selectedCB1.Checked
^ am.selectedCB2.Checked
^ am.selectedCB3.Checked
^ am.selectedCB4.Checked
^ am.selectedCB5.Checked
^ am.selectedCB6.Checked
^ am.selectedCB7.Checked
^ am.selectedCB8.Checked;
}
With that said, I would advise against using the XOR ^ operator, and consider something similar to nvoigt's answer, on the grounds that it is seldom used meaning many developers wouldn't be familiar with it, thereby impeding the code's readability.

Related

Ternary condition in c# logic not working as desired

I have written a ternary condition in c# which isnt evaluating correctly. I am checking if both condition satisfy then it should return true otherwise false. At the moment it is returning true even if one condition fails. So even if the docType is Flashnotes is true, the canView is setting to true. Consider this IoC.Resolve().Authorize("Put", "ManageDocuments")
always returning true and docType may or may not return true
doc.canView = IoC.Resolve<IClientAuthorizationService>().Authorize("Put", "ManageDocuments") ==
AuthAccessLevel.Full && i.DOCUMENT_TYPE_ID != (int) DocumentType.FlashNotes ||
i.DOCUMENT_TYPE_ID != (int)DocumentType.CallMeetingNotes ||
i.DOCUMENT_TYPE_ID != (int)DocumentType.OtherNotes ||
i.DOCUMENT_TYPE_ID != (int)DocumentType.TearSheet
? true
: false;
If I've understood this correctly one of the i.DOCUMENT_TYPE_ID consditions must equate to true? Add parenthesis to equate that first.
doc.canView = IoC.Resolve<IClientAuthorizationService>().Authorize("Put", "ManageDocuments") ==
AuthAccessLevel.Full && (i.DOCUMENT_TYPE_ID == (int) DocumentType.FlashNotes ||
i.DOCUMENT_TYPE_ID == (int)DocumentType.CallMeetingNotes ||
i.DOCUMENT_TYPE_ID == (int)DocumentType.OtherNotes ||
i.DOCUMENT_TYPE_ID == (int)DocumentType.TearSheet)
Also there's no need for the true or false as it's already a bool.
I think what you're trying to do can be simplified into something like this:
var rejectedTypes = new[] { DocumentType.FlashNotes, DocumentType.CallMeetingNotes,
DocumentType.OtherNotes, DocumentType.TearSheet }.Cast<int>();
var accessLevel = IoC.Resolve<IClientAuthorizationService>()
.Authorize("Put", "ManageDocuments");
doc.canView = ((accessLevel == AuthAccessLevel.Full) &&
!rejectedTypes.Contains(i.DOCUMENT_TYPE_ID));
I think there's a mistake in the logic here. Try:
doc.canView = IoC.Resolve<IClientAuthorizationService>().Authorize("Put", "ManageDocuments") ==
AuthAccessLevel.Full && !(i.DOCUMENT_TYPE_ID == (int) DocumentType.FlashNotes ||
i.DOCUMENT_TYPE_ID == (int)DocumentType.CallMeetingNotes ||
i.DOCUMENT_TYPE_ID == (int)DocumentType.OtherNotes ||
i.DOCUMENT_TYPE_ID == (int)DocumentType.TearSheet);
It's an order of operations problem. You can find out more about ordering it here:
doc.canView = IoC.Resolve<IClientAuthorizationService>().Authorize("Put", "ManageDocuments") ==
AuthAccessLevel.Full && (i.DOCUMENT_TYPE_ID != (int) DocumentType.FlashNotes &&
i.DOCUMENT_TYPE_ID != (int)DocumentType.CallMeetingNotes &&
i.DOCUMENT_TYPE_ID != (int)DocumentType.OtherNotes &&
i.DOCUMENT_TYPE_ID != (int)DocumentType.TearSheet)
? true // Redundant code but included to show ternary operator
: false;

Get parent entity according to some property filter in child table

Id like to get all the parent that doesn't have in the signature table anything with
(Roleid 1 OR Roleid 2 OR Roleid 3) AND SignatureStatus IS <> NULL
RoleId - int: 0-13
SignatureStatus - bit: True, False, Null
I have this code but i still get the parent when i shouldn't and not getting it when i should..
result = Context.APP_AuthorityHasamaForm.Where(x =>
x.UpdateTypeId == (int)UpdateType.Unit && x.AuthorityNum == authorityUnit.AuthorityNum &&
x.InsertDate >= authorityUnit.FromDate && x.HasamaFormStatus == (int)Status.Valid &&
!(x.APP_SignatureAuthorityHasamaForm.Any(s =>
s.RoleId == (int)Role.EligibilityWorker1 || s.RoleId == (int)Role.DepartmentManager2 ||
s.RoleId == (int)Role.Treasurer3 && ((bool)s.SignatureStatus || !(bool)s.SignatureStatus)))).ToList();
How about changing it to be this?
!(x.APP_SignatureAuthorityHasamaForm.Any(s =>
(s.RoleId == (int)Role.EligibilityWorker1 || s.RoleId == (int)Role.DepartmentManager2 ||
s.RoleId == (int)Role.Treasurer3) && s.SignatureStatus.HasValue))).ToList();
I don't have your class structure but here goes few fixes , put brackets outside OR condition and use .HasValue for checking non null :
.Any(s =>
(s.RoleId == (int)Role.EligibilityWorker1 || s.RoleId == (int)Role.DepartmentManager2 ||
s.RoleId == (int)Role.Treasurer3) && ((bool)s.SignatureStatus.hasValue).ToList();

Multiple using of || and && operands

I have a query using Entity Framework. It has many different operands and I am confused with its priority. I am getting the wrong result. I need all records that IsPaid == true or IsPaid == null, also all records must be TypeId == 1 or TypeId == 2, also must be CityId == 1 and CategoryId == 2. For some reason it doesn't evaluate CityId and CategoryId.
What am I doing wrong? Thanks.
var list = db.Ads.Where (x =>
x.IsPaid == true || x.IsPaid == null &&
x.TypeId == 1 || x.TypeId == 2 &&
x.CityId == 1 && x.CategoryId == 2
).ToList();
The best way to solve this problem is using brackets.
You should always use them even if you know the binding prioritys, to increase readability of your code.
(x.IsPaid == true || x.IsPaid == null) && (x.TypeId == 1 || x.TypeId == 2) && x.CityId == 1 && x.CategoryId == 2
&& has a higher proirity than ||
So false && false || true would be translated to (false && false) || true => true
Sidenote as mentioned by #Joey:
Instead of (x.IsPaid == true || x.IsPaid == null) you can write (x.IsPaid != false).
Due to operator precedence, && binds higher than ||.
If you chain Where statements, it's more clear what happens:
var list = db.Ads
.Where(x => x.IsPaid == true || x.IsPaid == null)
.Where(x=> x.TypeId == 1 || x.TypeId == 2)
.Where(x=> x.CityId == 1)
.Where(x=> x.CategoryId == 2)
.ToList();
&& has a higher precedence than ||, just like in math. So, effectively your condition is the following:
x.IsPaid == true ||
x.IsPaid == null && x.TypeId == 1 ||
x.TypeId == 2 && x.CityId == 1 && x.CategoryId == 2
If any of those expressions on separate lines are true, the whole expression is true. You have to use parentheses to clarify here:
(x.IsPaid == true || x.IsPaid == null) &&
(x.TypeId == 1 || x.TypeId == 2) &&
x.CityId == 1 &&
x.CategoryId == 2
Try this:
var list = db.Ads.Where (
(x => x.IsPaid == true || x.IsPaid == null) &&
(x.TypeId == 1 || x.TypeId == 2) &&
(x.CityId == 1 && x.CategoryId == 2)
).ToList();

Radiobutton Validation Using Correct Operator

Background
I'm trying to validate a group of 5 radiobuttons by showing a messagebox if none are selected.
My code
...
else if (assetsRb.Checked == false || fabricRb.Checked == false || fireRb.Checked == false || hsRb.Checked == false || partMRb.Checked == false)
{
MessageBox.Show("Please Select Assessment type.");
}
...
Question
I don't understand why this isn't working and always returns true, displaying the messagebox, even when radioboxes are checked?
I needed to use the && operator.
...
else if (assetsRb.Checked == false && fabricRb.Checked == false && fireRb.Checked == false && hsRb.Checked == false && partMRb.Checked == false)
{
MessageBox.Show("Please Select Assessment type.");
}
...

linq to sql nullable date issue

int ddlshopID = ddlSupervisorShop.SelectedItem == null ? 0 : ddlSupervisorShop.SelectedValue.ToInt32();
DateTime today = DateTime.Now;
List<int> supervisorShopList = shops.Select(a => a.ShopID).ToList<int>();
totalSales = (from ds in db.DailySales
join p in db.Products on ds.ProductID equals p.ProductID
where ds.IsActive == true &&
p.IsActive == true &&
ds.SaleDate.Value.Month == today.Month &&
ds.SaleDate.Value.Year == today.Year &&
ddlshopID == 0 ? supervisorShopList.Contains(ds.ShopID) : ds.ShopID == ddlshopID
group ds by new
{
p.ProductCategoryID,
p.IsActive,
}
into g
select new TotalPriceDivision
{
TotalPrice = g.Sum(a => a.Quantity * a.PerPrice),
DivisionID = g.Key.ProductCategoryID
}).ToList<TotalPriceDivision>();
In this piece of code the line
ds.SaleDate.Value.Month == today.Month && ds.SaleDate.Value.Year == today.Year
doesn't affect query result. ds.SaleDate is nullable date value (not datetime) in the database. Is it because of that? If yes, how can I solve this?
where ds.IsActive && // don't compare boolean with true
p.IsActive &&
ds.SaleDate.HasValue && // add this condition
ds.SaleDate.Value.Month == today.Month &&
ds.SaleDate.Value.Year == today.Year &&
ddlshopID == 0 ? supervisorShopList.Contains(ds.ShopID) : ds.ShopID == ddlshopID
I've found what is wrong with this.
surprisingly,incredibly and stupidly
if I order my query as
where ds.IsActive == true
&& p.IsActive == true
&& ds.SaleDate.Value.Month == today.Month
&& ds.SaleDate.Value.Year == today.Year
&& ddlshopID == 0 ? supervisorShopList.Contains(ds.ShopID) : ds.ShopID == ddlshopID
date conditions doesn't effect query result and it returns wrong.
İf I order it as
where ds.IsActive == true
&& p.IsActive == true
&& ddlshopID == 0 ? supervisorShopList.Contains(ds.ShopID) : ds.ShopID == ddlshopID
&& ds.SaleDate.Value.Month == today.Month
&& ds.SaleDate.Value.Year == today.Year
it works as I expected
I still can't beleive how is it possible. And if you think there must be another reason please explain me.

Categories

Resources