Reputation:
I have about 9 of these just with different values for were "sourceVal" and "Source" is. I would like to make a method and just pass those two values for each one so my code is cleaner. Is there an easy way to make a method out of this?
foreach (KeyValuePair<int?, string> sourceVal in Source) {
try {
if (p.LeadOriginDetail != null) {
if (sourceVal.Value.ToUpper() == p.LeadOriginDetail.ToUpper()) {
sourceid = sourceVal.Key;
break;
} else {
sourceid = null;
}
} else {
sourceid = null;
}
} catch (Exception ex) {
CPCUtilities.LogGeneral("Error: " + ex.ToString());
}
}
Thanks!
Upvotes: 0
Views: 169
Reputation: 726479
If you would like to refactor it manually, try this:
int? Find(IEnumerable<KeyValuePair<int?, string>> items, string origin) {
int? resId = null;
foreach (KeyValuePair<int?, string> sourceVal in items) {
try {
if (origin != null) {
if (sourceVal.Value.ToUpper() == origin.ToUpper()) {
resId = sourceVal.Key;
break;
} else {
resId = null;
}
} else {
resId = null;
}
} catch (Exception ex) {
CPCUtilities.LogGeneral("Error: " + ex.ToString());
}
}
return resId;
}
Now you can invoke this logic as follows:
var sourceId = Find(Source, p.LeadOriginDetail);
var marketId = Find(Market, p.LeadOriginDetail);
var businessUnitId = Find(BusinessUnit, p.LeadOriginDetail);
There is an easier way of getting the first matching ID using LINQ - it is nearly always a better choice than rolling your own loop, let alone making nine similar loops.
Upvotes: 1
Reputation: 108790
I'd create a method like the following:
int? FindKeyForValue(IEnumerable<KeyValuePair<int?,string> sequence,string valueToFind)
{
if(valueToFind!=null)
return sequence
.Where(string.Equals(pair.Value,valueToFind,StringComparison.CurrentCultureIgnoreCase))
.Select(pair=>pair.Value)
.FirstOrDefault();
else
return null;
}
Or if you prefer:
int? FindKeyForValue(IEnumerable<KeyValuePair<int?,string> sequence,string valueToFind)
{
if(valueToFind!=null)
return sequence
.FirstOrDefault(string.Equals(pair.Value,valueToFind,StringComparison.CurrentCultureIgnoreCase))
.Key;
else
return null;
}
which is shorter, but IMO harder to read.
You should choose the culture to use deliberately. In most cases you'll want to use an invariant culture, not the current culture. I used the current culture in my code, since that's closest to your original code.
Upvotes: 0
Reputation: 4573
I don't understand what you mean by "different value for sourceVal" as sourceVal is a local variable to the loop.
But if the problem is that you have different types that can replace "Source" type, then you extract the snippet into a method that accepts an argument of type
IEnumerable<KeyValuePair<int?, string>>
Upvotes: 0
Reputation: 18843
Create a Method called YourSampleMethod();//for example and rename it to what ever you want the method name to be
private static void YourSampleMethod()
{
foreach (KeyValuePair<int?, string> sourceVal in Source)
{
try
{
if (p.LeadOriginDetail != null)
{
if (sourceVal.Value.ToUpper() == p.LeadOriginDetail.ToUpper())
{
sourceid = sourceVal.Key; break;
}
else
{
sourceid = null;
}
}
else
{
sourceid = null;
}
}
catch (Exception ex)
{
CPCUtilities.LogGeneral("Error: " + ex.ToString());
}
}
}
Upvotes: 0
Reputation: 13215
Make an array using new ClassName[] { }
syntax:
foreach([itemclass] Source in new [collectionclass][] { Source1, Source2, Source3, Source4... }) {
foreach (KeyValuePair<int?, string> sourceVal in Source) {
// everything else
}
}
Upvotes: 0
Reputation: 241583
Yes, rewrite it to use FirstOrDefault
and then you can easily write that into a method (return type int?
and parameter IEnumerable<KeyValuePair<int?, string>>
).
Upvotes: 2