How to run a loop in the statement in C#? [closed] - c#

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
So i have a let's say 100 statements in C#.
CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU01_IEmergOpenAct.Force(false);
CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU02_IEmergOpenAct.Force(false);
CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU03_IEmergOpenAct.Force(false);
And so on till DCU100. I want to run a loop in that way that I can access all the statements DCU01..DCU100.
EDIT : Everything before Force. is a signal container. That's why can't use Array or List (No overload method).

You can use reflection
var obj = CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst;
for(int i = 0; i < yourCount; i++){
var prop = obj.GetType().GetProperties().FirstOrDefault(x => x.Name == string.Format("DCU{0}_IEmergOpenAct", i));
if(prop != null){
var propValue = (YourObjectType)prop.GetValue(CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst);
propValue.Force(False);
}
}
Maybe you need to format the i variable to "00" or something in the string.Format() call

If CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU01_IEmergOpenAct is a type name (instead of a member), then you can try the following approach:
IEnumerable<MethodInfo> methods =
Enumerable.Range(1, 100)
.Select(i => $"CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU{i:D2}_IEmergOpenAct")
.Select(t => Type.GetType(t))
.Select(t => t.GetMethod("Force", BindingFlags.Public | BindingFlags.Static));
foreach (MethodInfo force in methods)
force.Invoke(null, new object[] { false });

Option 1
Useful if you don't mind writing the whole list once and need it multiple times.
Put it into all individual items into a List/Array and loop over it.
var list = new List<IEmergOpenAct>() { // I am guessing a type here
CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU01_IEmergOpenAct,
CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU02_IEmergOpenAct,
CCU_O.MWT.DRSa09_DrEmrgOpn.DRSa09_DrEmrgOpnCst.DCU03_IEmergOpenAct,
};
foreach (var act in list)
{
act.Force(false);
}
Option 2
Useful if you don't want to type the whole list but they follow a unique pattern.
Open the Type/Namespace DRSa09_DrEmrgOpnCst via Reflection and get all Types that match the "DCU??_IEmergOpenAct" pattern. Put them into a list like in option 1 and loop over them as shown above.

Related

Best way to loop through a string Array and Compare values with a List of objects? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Still learning C# - is it possible to loop through elements of a string array and compare it with the values in a list of objects? eg:
var allFolks = new List<Folks>();
allFolks = Folks.GetAll();
string[] enteredNames = Array.ConvertAll(inputNames.Text.Split(','), p => p.Trim());
foreach (var eName in enteredNames)
{
//if eName is not in the list of allFolks throw an exception
if (!allFolks.Name.Contains(eName))
throw new Exception ("Name not found");
}
What would be the best way to compare each entered name (stored in an array) with the names in the list of type Folks? Is it possible to use Lambda Expression in the example above?
string[] enteredNames = inputNames.Split(',');
foreach (var eName in enteredNames)
{
if (!allFolks.Any(e => e.Name.Contains(eName.Trim()))
{
throw new Exception("Name not found");
}
}
Taking a string of inputNames and calling .Split(',') will separate the string by each comma and save them into a string[].
Then if (!allFolks.Any(e => e.Name.Contains(eName))) will throw the exception if eName does not exist within any object in the List<Folks>.
It's a difficult to asnwer for "what is the best" question: the best in performance, memory, readability?
I suggest using Linq in order to query the collections:
using System.Linq;
...
// Do we have any unknown name (i.e. any namy name except folks' names)?
bool hasUnknownName = inputNames
.Text
.Split(',', StringSplitOptions.TrimEntries)
.Except(allFolks.Select(folk => folk.Name))
.Any();
if (hasUnknownName)
throw ... //TODO: don't throw Exception, but some derived class
Linq solution
Often is more readable
Faster then initial one (if allFolks and inputNames are large)
Edit: As Eric J. puts in the comment below, it's possible to improve performance when allFolks is large and has duplicates. We can, for instance, efficiently compare with (precomputed) unique names only:
// We precompute unique names to test
HashSet<string> uniqueNames = new HashSet<string>(allFolks
.Select(folk => folk.Name));
...
bool hasUnknownName = inputNames
.Text
.Split(',', StringSplitOptions.TrimEntries)
.Any(name => !uniqueNames.Contains(name));
if (hasUnknownName)
throw ... //TODO: don't throw Exception, but some derived class
If I am to infer your requirements, I think you wish to validate a list of names, held as strings, and check to ensure each one matches the Name of one of your Folk objects.
You can do it with LINQ this way:
bool invalid = enteredNames.Any( x => !allFolks.Any( y => y.Name == x) );
For a large list of Folk objects, you'll get better performance if you extract the unique set of names to a variable of its own.
var knownGoodNames = allFolks.Select( x => x.Name ).ToHashSet();
bool invalid = enteredNames.Any( x => !knownGoodNames.Contains(x) );

How to increase performance of foreach loop? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
How to increase performance (it takes about 10 seconds) of this foreach loop
foreach (var item in pList)
{
var foundedItem = source.FirstOrDefault(x => x.LongRecordId == item.LongRecordId);
if (foundedItem != null && !selectionList.Contains(foundedItem))
{
foundedItem.Readonly = pReadonly;
selectionList.Add(foundedItem);
}
}
In case source as well as pList are long, you may try converting source into a Dictionary:
// Provinding that all LongRecordId are distinct
var dict = source
.ToDictionary(item => item.LongRecordId, item => item);
...
foreach (var item in pList) {
MyRecord foundItem = null; //TODO: Put the right type here
// Instead of O(N) - FirstOrDefault we have O(1) TryGetValue
if (dict.TryGetValue(item.LongRecordId, out foundItem)) {
foundItem.Readonly = pReadonly;
selectionList.Add(foundItem);
}
}
Edit: In case you want to ensure that selectionList contains distinct items only (see Ferhat Sayan's comment) try HashSet
...
HashSet<MyRecord> selectedHash = new HashSet<MyRecord>(selectionList);
foreach (var item in pList) {
MyRecord foundItem null; //TODO: Put the right type here
// Instead of O(N) - FirstOrDefault we have O(1) TryGetValue
if (dict.TryGetValue(item.LongRecordId, out foundItem)) {
foundItem.Readonly = pReadonly;
selectedHash.Add(foundItem);
}
}
selectionList = selectedHash.ToList();
I suggest to profile that piece of code.
I guess the most time consuming call is the FirstOrDefault-Extension Method.
To use for instead of foreach is unlikely to grant you much if any performance gains.
Most probably your problems stems from your context variables, maybe a very large source list?
Overall, this code section is maybe not the best place to look for performance improvements. If this is the only place, you should think about a redesign.
If you have very large lists and do not fear concurrency issues you could go the parallel or multi-processing route. parallel.foreach is a cheap way to do some tests.
The use of a Dictionary instead of a List should speedup things. If you go with a HashSet (to yield the benefit of uniqunes) be aware to implement a proper IEqualityComparer, or you could even lose performance when you add a huge number of items relying on the DefaultComparer.

how to remove duplicate values from a list but want to include all empty strings from that list [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a list of objects in which I want to remove duplicates but does not want to remove blank objects.
I am using DistinctBy lambda expression. But it also removes duplicates.
Can anyone help me in providing the condition that passes blank and checks only that object which has proper value in an object ?
You could use a very simple extension method:
public static void DistinctKeepingEmptyStrings(this List<string> list) {
var support = new List<string>(list);
HashSet<string> knownValues = new HashSet<string>();
foreach (var aString in list) {
if (aString == "" || knownValues.Add(aString)) {
support.Add(aString);
}
}
list.Clear();
list.AddRange(support);
}
Example:
var list is in this case a list consisting of all duplicates (minus the empty strings)
then I just iterate through the duplicates and remove them from the listOfValues.
List<string> listOfValues = new List<string> {"test", "test2", "", "test2", "", ""};
var list = listOfValues.GroupBy(r => r).SelectMany(grp => grp.Skip(1)).Where(r => r != "");
foreach (var aVar in list)
{
listOfValues.Remove(aVar);
}

Update of one list automatically updates another list [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have one original list and two temporary lists.
Based on certain condition, I am adding data from the original list(after modifying certain values) to these temp lists. But changes made in one temp list via this copy operation is updating the other temp list as well.
List<UserLMSSubFunc> lstUserLMSSubFunc = null;
List<UserLMSSubFunc> lstUserLMSSubFuncTemp1 = new List<UserLMSSubFunc>();
List<UserLMSSubFunc> lstUserLMSSubFuncTemp2 = new List<UserLMSSubFunc>();
foreach (Constructor subFnc in originalList)
{
foreach (KeyValuePair<string, string> kv in OriginalList)
{
if (kv.Value.ToUpper() == subFnc.SubFuncCode.ToUpper())
{
if (subFnc.FuncCode == null)
{
subFnc.FuncCode = kv.Key;
templist1.Add(subFnc);
}
else
{
subFnc.FuncCode = kv.Key;
Templist2.Add(subFnc);
}
}
}
}
The reason why the data in your lists is changing is due to the reference / value type mishmash. Your lists hold only a reference to an object inside that list. Therefore whenever you change your object which you have pulled from one of the lists I suspect it is the same object which is located in the other two as well, hence the change which seemingly propagates itself across the lists.
Use Setter
private var temp1 = new List<Package>();
public List<Package> temp1
{
set { temp1 = value;
update your temp2}
get { return temp1; }
}

Is it possible to recreate this statement without using a foreach? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C#: Is operator for Generic Types with inheritance
Is it possible to add a list into another list whilst changing class type from Deal to DealBookmarkWrapper without using the foreach statement?
var list = new List<IBookmarkWrapper>();
foreach (var deal in deals)
{
list.Add(new DealBookmarkWrapper(deal));
}
Thanks.
If you want the exact equivalent:
var list = deals.Select(d => new DealBookmarkWrapper(d))
.Cast<IBookmarkWrapper>()
.ToList();
But if you're just iterating over the elements and don't really need a List, you can leave off the call to GetList().
var list = deals.Select(d => new DealBookmarkWrapper(d))
.Cast<IBookmarkWrapper>()
.ToList();
How about
var list = deals.ConvertAll(item=>new DealBookmarkWrapper(item));
The question explicitly ask for 'adding a list into another list', so this one could be interesting too:
var list = new List<IBookmarkWrapper>(); //already existing
...
deals.Aggregate(list, (s, c) =>
{
s.Add(new DealBookmarkWrapper(c));
return s;
});

Categories

Resources