How to combine 3 action before running loop? - c#

the code
Settings setting_ = .... // not null
foreach( var item in ItemsCollection)
{
var tt1 = item.GetTT1();
var tt2 = item.GetTT2();
if( tt2 != null && tt1 != null )
{
if( !string.IsNullOrEmpty( settings_.Name ) )
{
tt2.Rename( tt1, setting_.Name );
}
if( setting_ .Settings != null )
{
tt2.ChangeSettings( tt1, setting_.Settings );
}
if( setting_ .Location != null )
{
tt2.ChangeLocation( tt1, setting_.Location );
}
}
}
Because the setting_ is not change at any iteration of the foreach loop => i need to check only once the 3 if .... ( before get into the foreach loop )
But the tt1 & tt2 are change each foreach iteration ...
How can i write this code better with only one check of the setting_ ?
one possible is this
private void defineAction( TT1 tt1 , TT2 tt2, Setting setting )
{
List<Action> action = new List<Action>();
if( !string.IsNullOrEmpty( settings_.Name ) )
{
action.Add( () => tt2.Rename( tt1, setting_.Name )
}
if( setting_ .Settings != null )
{
action.Add( () => tt2.ChangeSettings( tt1, setting_.Settings );
}
if( setting_ .Settings != null )
{
action.Add( () => tt2.ChangeLocation( tt1, setting_.Location );
}
}
and use the List to make the action ..
but i need to call this method each iteration and i want to make it better

Now that I understand from your previous comments what you're trying to do you can create a collection of actions rather than using simple if statements. If may or may not be better performing, since you'd have the cost of the iterator. If the collection is large, it would probably be useful to check if you're going to do anything before iterating over it.
Settings setting_ = .... // not null
var actions = new List<Action<TT1,TT2>>();
if (!string.IsNullOrEmpty(setting_.Name))
{
actions.Add((t1,t2) => t2.Rename(t1, setting_.Name););
}
if (setting_.Settings != null)
{
actions.Add((t1,t2) => t2.ChangeSettings(t1, settings_.Settings));
}
if (setting_.Location != null)
{
actions.Add((t1,t2) => t2.ChangeLocation(t1, settings_.Location));
}
if (actions.Any())
{
foreach( var item in ItemsCollection)
{
var tt1 = item.GetTT1();
var tt2 = item.GetTT2();
if (tt1 == null || tt2 == null)
{
continue;
}
foreach (var action in actions)
{
action(tt1,tt2);
}
}
}
Though I still think it's easier if you just precompute the conditions - I was confused by setting_.Settings before.
Settings setting_ = .... // not null
var changeName = !string.IsNullOrEmpty(setting_.Name);
var changeSetting = setting_.Settings != null;
var changeLocation = setting_.Location != null;
if (changeName || changeSetting || changeLocation)
{
foreach (var item in ItemCollection)
{
var tt1 = item.getTT1();
var tt2 = item.getTT2();
if (tt1 == null || tt2 == null)
{
continue;
}
if (changeName)
{
tt2.Rename(tt1, setting_.Name);
}
if (changeSetting)
{
tt2.ChangeSettings(tt1, settings_.Settings);
}
if (changeLocation)
{
tt2.ChangeLocation(tt1, settings_.Location);
}
}
}

It took me a while to decipher your question but I think I understand you. Here's what you could do:
var actions = new List<Action<Item, Item>>();
if (!string.IsNullOrEmpty(setting_.Name))
{
actions.Add((tt1, tt2) =>
{
if (tt1 != null && tt2 != null)
tt2.Rename(tt1, setting_.Name);
});
}
if (setting_.Settings != null)
{
actions.Add((tt1, tt2) =>
{
if (tt1 != null && tt2 != null)
tt2.ChangeSettings(tt1, setting_.Settings);
});
}
if (setting_.Settings != null)
{
actions.Add((tt1, tt2) =>
{
if (tt1 != null && tt2 != null)
tt2.ChangeLocation(tt1, setting_.Location);
});
}
foreach (var item in itemCollection)
{
var tt1 = item.GetTT1();
var tt2 = item.GetTT2();
actions.ForEach(a => a(tt1, tt2));
}

Related

Getting System.StackOverflowException , in a recursive function call?

I have to two function which is used to find tags inside the tags like, there is a tag A=B(C(D(E))) so i have to find all the tags inside B then all the tags inside C and so on. I write two function but getting the error System.StackOverflowException. In the first function i am providing the tag ID and against that tag id i am getting getNestesCalTagsId and then calling the getNestedCalTagsIngredients() function. But when there are lot of recursion calls i get the error System.StackOverflowException. Below is my whole code.
public List<int?> getNestedCalTags(int? calTagId)
{
var getNestesCalTagsId = db.Dependencies_Metrix.Where(x => x.Cal_Tag_P_Id == calTagId && x.Status == true && x.Cal_Tag_Id_FK!=null).Select(x => x.Cal_Tag_Id_FK).ToList();
if (getNestesCalTagsId.Count > 0)
{
nestedCalFTags.AddRange(getNestesCalTagsId);
foreach (var item in getNestesCalTagsId)
{
if (item != null)
{
getNestedCalTagsIngredients(item.Value);
}
}
}
if (nestedCalFTags.Count > 0)
{
int countedTags = nestedCalFTags.Count;
List<int?> tags = new List<int?>(nestedCalFTags);
for (int i = 0; i < tags.Count; i++)
{
if (tags[i] != null)
{
getNestedCalTagsIngredients(tags[i].Value);
}
}
}
return nestedRawTags;
}
public bool getNestedCalTagsIngredients(int nestCalTagId)
{
var getCalTags = db.Dependencies_Metrix.Where(x => x.Cal_Tag_P_Id == nestCalTagId && x.Status == true).ToList();
if (getCalTags.Count > 0)
{
foreach (var item in getCalTags)
{
if (item.Cal_Tag_Id_FK != null)
{
var getNestedCalTagParent = db.Dependencies_Metrix.Where(x => x.Cal_Tag_P_Id == item.Cal_Tag_Id_FK && x.Status == true && x.Cal_Tag_Id_FK!=null).Select(x => x.Cal_Tag_Id_FK).ToList();
if (getNestedCalTagParent != null)
{
nestedCalFTags.AddRange(getNestedCalTagParent);
getNestedCalTags(item.Cal_Tag_Id_FK);
}
}
else
{
var rawTagId = db.Dependencies_Metrix.Where(x => x.Cal_Tag_P_Id == item.Cal_Tag_P_Id && x.Real_Tag_Id_FK!=null).Select(x => x.Real_Tag_Id_FK).ToList();
if (rawTagId != null)
{
foreach (var rawItem in rawTagId)
{
if (rawItem!=null)
{
if (nestedRawTags.IndexOf(rawItem.Value) == -1)
{
nestedRawTags.Add(rawItem.Value);
}
}
}
}
nestedCalFTags.Remove(nestCalTagId);
}
}
}
return true;
}

How to overcome foreach loop for list object dynamically

I'm swapping my values in List Object on some conditions and update List Object value.
Currently, what I'm doing is
- Looping on each object through List
- Check If condition is net
- Swap values
public static void SwapMinMaxIfNull<T>(this IEnumerable<T> rows, string reportfor)
{
if (reportfor.Equals("Comparison"))
{
var row = rows as IEnumerable<RiskBoardDataToExport>;
try
{
if (rows.Any())
{
var Tests = row.Where(min => min.MinGaitSpeed == null && min.MaxGaitSpeed != null).ToList();
if (Tests != null)
{
foreach (RiskBoardDataToExport test in Tests)
{
test.MinGaitSpeed = test.MaxGaitSpeed;
test.MaxGaitSpeed = null;
}
}
// again check for next object
Tests = row.Where(min => min.MinTUGTime == null && min.MaxTUGTime != null).ToList();
if (Tests != null)
{
foreach (RiskBoardDataToExport test in Tests)
{
test.MinTUGTime = test.MaxTUGTime;
test.MaxTUGTime = null;
}
}
// again check for next object
Tests = row.Where(min => min.MinBergScoreSpeed == null && min.MaxBergScoreSpeed != null).ToList();
if (Tests != null)
{
foreach (RiskBoardDataToExport test in Tests)
{
test.MinBergScoreSpeed = test.MaxBergScoreSpeed;
test.MaxBergScoreSpeed = null;
}
}
//.. for brevity
}
}
}
Can I do it in better way? I know about PropertyInfo i.e. Can check property name and get value etc, but, not having any hint to get this done.
Thanks
It's not exactly what you're asking for, but you can combine the clauses in your Where statements and then have a few if statements in the body:
public static void SwapMinMaxIfNull(this IEnumerable<RiskBoardDataToExport> rows,
string reportfor)
{
if (rows = null) return;
if (reportfor.Equals("Comparison", StringComparison.OrdinalIgnoreCase))
{
foreach (var row in rows.Where(r =>
(r.MinGaitSpeed == null && r.MaxGaitSpeed != null) ||
(r.MinBergScoreSpeed == null && r.MaxBergScoreSpeed != null) ||
(r.MinBergScoreSpeed == null && r.MaxBergScoreSpeed != null)))
{
if (row.MinGaitSpeed == null)
{
row.MinGaitSpeed = row.MaxGaitSpeed;
row.MaxGaitSpeed = null;
}
if (row.MinTUGTime == null)
{
row.MinTUGTime = row.MaxTUGTime;
row.MaxTUGTime = null;
}
if (row.MinBergScoreSpeed == null)
{
row.MinBergScoreSpeed = row.MaxBergScoreSpeed;
row.MaxBergScoreSpeed = null;
}
}
}
}
As this is an operation where order of the items in the list does not matter, you can easily speed this up by parallelization (you can read up on that here).
So, what you should do, is handle this foreach loop in a parallel way and combine it with Rufus L's optimized code for the fastest result.
var rows = rows.Where(r =>
(r.MinGaitSpeed == null && r.MaxGaitSpeed != null) ||
(r.MinBergScoreSpeed == null && r.MaxBergScoreSpeed != null) ||
(r.MinBergScoreSpeed == null && r.MaxBergScoreSpeed != null))
Parallel.ForEach(rows, (row) => {
{
if (row.MinGaitSpeed == null)
{
row.MinGaitSpeed = row.MaxGaitSpeed;
row.MaxGaitSpeed = null;
}
if (row.MinTUGTime == null)
{
row.MinTUGTime = row.MaxTUGTime;
row.MaxTUGTime = null;
}
if (row.MinBergScoreSpeed == null)
{
row.MinBergScoreSpeed = row.MaxBergScoreSpeed;
row.MaxBergScoreSpeed = null;
}
}
Note that this requires the System.Threading.Tasks namespace, that's where the Parallel class is.

how can i get property and value of a class by reflection

i started with this! and i would like to avoid this
private IQueryable<Customer> FilterResult(string search, List<Customer> dtResult, List<string> columnFilters)
{
IQueryable<Customer> results = dtResult.AsQueryable();
results = results.Where(p => (search == null || (p.Name != null && p.Name.ToLower().Contains(search.ToLower()) || p.City != null && p.City.ToLower().Contains(search.ToLower())
&& (columnFilters[0] == null || (p.Name != null && p.Name.ToLower().Contains(columnFilters[0].ToLower())))
&& (columnFilters[1] == null || (p.City != null && p.City.ToLower().Contains(columnFilters[1].ToLower())))
);
return results;
}
by using reflection maybe.... because imagine i have 100 properties it would be easy to mess up ...so i tried this way i would like to use reflection to loop on all properties instead of making references to each of them(properties)
public IQueryable<Aangifte> FilterColumn<T>()
{
try
{
List<Aangifte> v = AangifteGetData.GetData(StartDate, EndDate);
List<Aangifte> v2 = new List<Aangifte>();
Aangifte Foo = new Aangifte();
List<string> propertEntity = new List<string>();
var search = Request.Form.GetValues("search[value]").FirstOrDefault();
int count = -1;
var results = v.AsQueryable();
List<string> columnName = new List<string>();
foreach (var prop in Foo.GetType().GetProperties())
{
var t = "";
if (!prop.Name.Contains("FORMAT"))
{
TVALUE = prop.GetValue(Foo, null);
t= prop.Name;
propertEntity.Add(t);
count++;
}
if (count < propertEntity.Count())
{
var newt = t;
var Z = Request.Form.GetValues("columns[" + count + "][search][value]").FirstOrDefault();
results = results.Where
(
p => (search == null || (t != null && t.ToLower().Contains(search.ToLower())))
&& (Request.Form.GetValues("columns[" + count + "][search][value]").FirstOrDefault() == null || (t != null && t.ToLower().Contains(Request.Form.GetValues("columns[" + count + "][search][value]").FirstOrDefault().ToLower())))
);
}
}
return results;
}
catch (Exception EX)
{
throw EX;
}
}

Refactor if statements

What is a best way for refactor "if" statements?
My method fragment:
if (code == SystemCode.Enum1.ToString())
{
user.IsEnum1 = result != null;
}
if (code == SystemCode.Enum2.ToString())
{
user.IsEnum2 = result != null;
}
if (code == SystemCode.Enum3.ToString())
{
user.IsEnum3 = result != null;
}
I would try this approach:
enum MyEnum
{
Enum1,
Enum2,
Enum3
}
class User
{
Dictionary<MyEnum, bool> enumList;
public void InitEnumList()
{
enumList = new Dictionary<MyEnum, bool>();
foreach (var item in Enum.GetValues(typeof(MyEnum)))
{
//Set the default key-value pairs
enumList.Add((MyEnum)item, false);
}
}
}
Switch statement is one of the good option for avoiding multiple if statements
Try this:
if (( !(code != ((int)SystemCode.Enum1).ToString() || (user.IsEnum1 = result != null).ToString().Length > 0))
|| !(code != ((int)SystemCode.Enum2).ToString() || (user.IsEnum2 = result != null).ToString().Length > 0)
|| !(code != ((int)SystemCode.Enum3).ToString() || (user.IsEnum3 = result != null).ToString().Length > 0))
{
return;
}
I know it looks complex but isn't that what you wanted. Let me know if you have any queries.

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;
}

Categories