Compare two lists on one property and dont add duplicate - c#

Hello so for some reason using various examples i havent been able to solve this.
So i have two lists one containing global values and one vlues that are set on a specific property. What i want to achieve is compare the two lists and keep the specific ones and then add the global ones that are not in the specific list based on its name.
i have tried this
var pidConfigValues = await _database.GetConfigurationValuesForPid(productGroup);
var globalConfigValues = await _database.GetGlobalConfigurationValues();
var allConfigs = pidConfigValues.Where(c => globalConfigValues.All(d => c.Name != d.Name)).ToList();
I guess something is wrong with the Where condition because the allConfigs ends up as empty. The both variables that gets compared are lists of same type of object
Example data
pidConfigValues would consist of objects like
Name: config.myConfig,
Pid: 2,
Value: 1
and globalConfigValues would be like
Name: config.myConfig,
Pid: Null,
Value: 0
Name: config.someOtherConfig,
Pid: Null,
Value: 1
So in the example above i would want allConfigs to be
Name: config.myConfig,
Pid: 2,
Value: 1
Name: config.someOtherConfig,
Pid: Null,
Value: 1
So in allConfigs only the config.myConfig with pid would be shown and from global only add the ones that does not exist in the specific one

Here is one way of doing it:
var pidConfigValues = new List<Config>()
{
new Config() { Name = "config.myConfig", Pid = 2, Value = 1}
};
var globalConfigValues = new List<Config>()
{
new Config() { Name = "config.myConfig", Pid = null, Value = 0},
new Config() { Name = "config.someOtherConfig", Pid = null, Value = 1}
};
var result = pidConfigValues.Concat(globalConfigValues)
.GroupBy(x => x.Name)
.Select(x => x.First()) //if multiple entities have the same name pick the first one which will be the one from pidConfigValues

One solution would be to use Union in combination with a custom EqualityComparer that compares the configs based on their Name-property:
// in your code:
var allConfigs = pidConfigValues.Union(globalConfigValues, new MyConfigComparer()).ToList();
// sample for the comparer:
public class MyConfigComparer : IEqualityComparer<MyConfig>
{
public bool Equals(MyConfig c1, MyConfig c2)
{
if (object.ReferenceEquals(c1, c2))
return true;
if (c1 == null || c2 == null)
return false;
return c1.Name.Equals(c2.Name, StringComparison.Ordinal);
}
public int GetHashCode(MyConfig x)
{
return x.Name.GetHashCode();
}
}

Ciao, you can use Distinct (by rewriting EqualityComparer). Here working example:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var pidConfigValues = new List<Configuration>();
var globalConfigValues = new List<Configuration>();
Configuration pidConfigValue = new Configuration("config.myConfig", 2, 1);
Configuration globalConfigValue1 = new Configuration("config.myConfig", null, 0);
Configuration globalConfigValue2 = new Configuration("config.someOtherConfig", null, 1);
globalConfigValues.Add(globalConfigValue1);
pidConfigValues.Add(pidConfigValue);
globalConfigValues.Add(globalConfigValue2);
List<Configuration> result = pidConfigValues.Concat(globalConfigValues)
.Distinct(new ConfigurationEqualityComparer()).ToList();
Console.WriteLine(String.Join(",", result));
Console.ReadLine();
}
}
public class Configuration
{
public string _name = "";
public Nullable<int> _pid = null;
public int _value = -1;
public Configuration(string name, Nullable<int> pid, int value)
{
this._name = name;
this._pid = pid;
this._value = value;
}
public override string ToString()
{
return "Name: " + this._name + " PID:" + this._pid + " Value:" + this._value + Environment.NewLine;
}
}
public class ConfigurationEqualityComparer
: EqualityComparer<Configuration>
{
public override bool Equals(Configuration c1, Configuration c2)
{
if (c1 == null && c2 == null)
return true;
else if (c1 == null || c2 == null)
return false;
else if (c1._name.Equals(c2._name))
{
if (c1._pid == null || c2._pid == null) return true;
else return false;
}
else
return false;
}
public override int GetHashCode(Configuration cnf)
{
int hCode = cnf._value ^ cnf._value;
return hCode.GetHashCode();
}
}
}
Explanation: Concat two lists and get only Distinct values. Equality comparer must be rewrited because we are using objects so we have to define which object is equal to another.

So your case is complicated to be solved by simple union or join operation. But simple enough to be solved by some simple select and concat operations.
What you need is to loop all loaded pidConfigValues and override a specific property with the global configuration, and then create a collection containing all unique configurations. Is that correct?
If so the solution could be like this:
var pidConfigValues = await _database.GetConfigurationValuesForPid(productGroup);
var globalConfigValues = await _database.GetGlobalConfigurationValues();
// loop through all pidConfigs and override their Pid value if matching global config exists
var allConfigs = pidConfigValues.Select(c =>
{
var matchingGlobalConfig = globalConfigValues.FirstOrDefault(g => g.Name == c.Name);
if (matchingGlobalConfig != null)
{
c.Pid = matchingGlobalConfig.Pid;
}
return c;
}).ToList();
// Find all global configs that are not matching any pidConfigValues
var productNames = pidConfigValues.Select(p => p.Name).ToArray();
var nonMatchingGlobalConfigs = globalConfigValues.Where(g => !productNames.Contains(g.Name)).ToArray();
// add non-matching global-configs to all-configs collection
allConfigs = allConfigs.Concat(nonMatchingGlobalConfigs).ToArray();

Related

Compare two list's values and get the difference

I created a method that compares two lists' values and outputs the difference:
public static List<OT_Contact> Comparer(
List<OT_Contact> security_owner,
List<OT_Contact> borrower)
{
List<OT_Contact> nonborrowertrustor = security_owner.Except(borrower).ToList();
foreach (var nbt_list in nonborrowertrustor)
{
var list = nbt_list;
}
return nonborrowertrustor;
}
Can anyone tell me if there is something wrong with my code and how can I assign it to a variable, for example:
var result = Comparer(list1, list2);
Why are you not using Linq?
var trustys = security_owner
.Where(o => !borrower.Any(b=> b.Name == o.Name /* && compare more attributes from o and b */))
.ToList();
return trustys;
this will filter all items from security owner which aren't in borrower, using
(b=> b.Name == o.Name && .....)
as "equality measure".
Example:
using System.Collections.Generic;
using System.Linq;
internal class Program
{
public class OT_Contact
{
public int Age;
public string Email;
public string Name;
public OT_Contact(string name, string email, int age = int.MinValue)
{
Name = name;
Email = email;
Age = age;
}
public override string ToString()
{
return ($"{Name} {Email} " + (Age != int.MinValue ? Age.ToString() : "")).Trim();
}
}
static void Main(string[] args)
{
var owner = new List<OT_Contact>
{
new OT_Contact("paul","p#o", 5),
new OT_Contact("paul","pppp#o"),
new OT_Contact("mani","kkk"),
new OT_Contact("olaf", "olaf", 22)
};
var borr = new List<OT_Contact>
{
new OT_Contact("paul","popel#o", 5),
new OT_Contact("paul","pppp#o"),
new OT_Contact("mani","kkk",99),
new OT_Contact("olaf", "", 22)
};
var trust = owner.Where(o => !borr.Any(b => b.Name == o.Name && b.Email == o.Email)).ToList();
System.Console.WriteLine("Owner:\n " + string.Join("\n ", owner));
System.Console.WriteLine("\nBorrower:\n " + string.Join("\n ", borr));
System.Console.WriteLine("\nTrustys:\n " + string.Join("\n ", trust));
System.Console.ReadLine();
}
}
Output (Age is not important for equality, hence not inside the Any-Clause):
Owner:
paul p#o 5
paul pppp#o
mani kkk
olaf olaf 22
Borrower:
paul popel#o 5
paul pppp#o
mani kkk 99
olaf 22
Trustys:
paul p#o 5
olaf olaf 22
This example models the IEnumerable.Except(..) used in the question. It will find any owner that is not found in the borrower list. The euqality-condition only takes Name and Email under consideration. If it finds an borrower with the same Name and Email it will not output him in the resulting list.
Any borrower that is only in the owner list won't make it into to the result either - getting any borrower that is not in owner could be accomplished by simply swapping the lists around:
var onlyBorr = borr.Where(b => !owner.Any(o => o.Name == b.Name && o.Email == b.Email)).ToList();
A feasable implementation of an IEqualityComparer for this contrieved example could be
public class OT_ContactEqualityComparer : IEqualityComparer<OT_Contact>
{
public bool Equals(OT_Contact x, OT_Contact y)
{
if (x == null || y == null)
return false;
return (x.Name == y.Name && x.Email == y.Email);
}
public int GetHashCode(OT_Contact c)
=> (c.Name ?? "").GetHashCode() ^ (c.Email ?? "").GetHashCode();
}
which would allow the usage of IEnumerable.Except like this:
System.Console.WriteLine("\nIEquality:\n " + string.Join("\n ",
owner.Except(borr, new OT_ContactEqualityComparer())));

How to compare two lists in .NET

List<Employee> emplist = new List<Employee>();
emplist.Add(new Employee { Name = "Emp_1", BasicSalary = 1000, Id = Guid.NewGuid(), HRA = 100, DA = 10, TotalSalary = 1110 });
emplist.Add(new Employee { Name = "Emp_2", BasicSalary = 1000 * 2, Id = Guid.NewGuid(), HRA = 200, DA = 20, TotalSalary = 2220 });
emplist.Add(new Employee { Name = "Emp_3", BasicSalary = 1000 * 3, Id = Guid.NewGuid(), HRA = 300, DA = 30, TotalSalary = 3330 });
var result = empRep.CallSupportFindAll();
// CollectionAssert.AreEqual(emplist, result);
Assert.AreEqual(emplist, result);
var r1 = result[0];
Assert.AreEqual(r1.Name, emplist[0].Name);
Assert.AreEqual(r1.TotalSalary, emplist[0].TotalSalary);
Assert.AreEqual(r1.BasicSalary, emplist[0].BasicSalary);
I want to compare two lists emplist and result. Assert.AreEqual(r1.Name, emplist[0].Name); worked but if we have thousands of records then I need to write thousands of lines.
so please answer-- for one line code for compare two list...
thanks in advance
If I understand correctly, you simply have two instances of List<Employee> and you want to assert that they are equal. I.e. they have the same number of Employee instances, in the same order, with equal properties.
If so, this has nothing to do with FakeItEasy. You simply need a method of performing the assertion. Personally I would do this using Fluent Assertions.
result.Should().BeEquivalentTo(emplist);
You can use HashSet<> to compare the two lists.
First, define an equaliser like this
public class EmployeeComparer : IEqualityComparer<Employee>
{
public bool Equals(Employee x, Employee y)
{
if (x == null && y == null)
return true;
if (x == null || y == null)
return false;
//You can implement the equal method as you like. For instance, you may compare by name
if (x.Id == y.Id)
return true;
return false;
}
public int GetHashCode(Employee employee)
{
return employee.Id.GetHashCode();
}
}
Next, create 2 hash sets based on the input and the result of the method
var equaliser = new EmployeeComparer();
HashSet<Employee> inputHashset = new HashSet<Employee>(emplist ,equaliser );
HashSet<Employee> resultHashset = new HashSet<Employee>(result,equaliser);
Finally, assert the equality of the two sets. It means, instead of
Assert.AreEqual(emplist, result);
Do
Assert.IsTrue(inputHashset.SetEquals(resultHashset));
public bool compareTwolist<T>(List<T> lst1,List<T> lst2)
{
bool bresult = false;
if (lst1.GetType() != lst2.GetType())
{
return false;
}
//if any of the list is null, return false
if ((lst1 == null && lst2 != null) || (lst2 == null && lst1 != null))
return false;
//if count don't match between 2 lists, then return false
if(lst1.Count != lst2.Count)
return false;
foreach (T item in lst1)
{
T obj1 = item;
T obj2 = lst2.ElementAt(lst1.IndexOf(item));
Type type = typeof(T);
foreach (System.Reflection.PropertyInfo property in type.GetProperties())
{
string obj1Value = string.Empty;
string obj2Value = string.Empty;
if (type.GetProperty(property.Name).GetValue(obj1) != null)
obj1Value = type.GetProperty(property.Name).GetValue(obj1).ToString();
if (type.GetProperty(property.Name).GetValue(obj2) != null)
obj2Value = type.GetProperty(property.Name).GetValue(obj2).ToString();
//if any of the property value inside an object in the list didnt match, return false
if (obj1Value.Trim() != obj2Value.Trim())
{
bresult = false;
break;
}
}
}
return bresult;
}
yes, I got a solution by creating user define function and pass two lists which we want to compare..
and just check is var a is true or not
var a = compareTwolist(empwithoutid, resultwithoutid);
Assert.IsTrue(a);
The comparison methods suggested in the other answers require you to implement equals on all your objects. This doesn't scale well from a maintenance perspective. Also in some tests only subset of fields are to be compared. This means multiple compare or equals methods to be implemented. An alternative is stateprinter which dumps state to a string to compare against. It can even write and rewrite your asserts for you. See https://github.com/kbilsted/StatePrinter/blob/master/doc/AutomatingUnitTesting.md for more info on automation and https://github.com/kbilsted/StatePrinter/blob/master/doc/TheProblemsWithTraditionalUnitTesting.md for an in depth discussion on problems with unit testing as you are facing now.

How to getting distinct values by linq or lambda?

I have a list of items, and i try to getting unique items by distinct keys.
The class:
class TempClass
{
public string One { get; set; }
public string Two { get; set; }
public string Key
{
get
{
return "Key_" + One + "_" + Two;
}
}
}
I build the dummy list as follows:
List<TempClass> l = new List<TempClass>()
{
new TempClass(){ One="Da" , Two = "Mi"},
new TempClass(){ One="Da" , Two = "Mi"},
new TempClass(){ One="Da" , Two = "Mi"},
new TempClass(){ One="Mi" , Two = "Da"},
new TempClass(){ One="Mi" , Two = "Da"},
};
My question is - how get only 1 item? by check that does exist only unique key? unique item means that should to check that have there only one key that equals to "Key_Da_Mi" or "Key_Mi_Da"?
how to achieve that?
Group each of the items on a HashSet of strings containing both keys, use HashSet's set comparer to compare the items as sets (sets are unordered) and then pull out the first (or whichever) item from each group:
var distinct = l.GroupBy(item => new HashSet<string>() { item.One, item.Two },
HashSet<string>.CreateSetComparer())
.Select(group => group.First());
You should either implement equality comparison, or implement IEqualityComparer<T> with your specific logic:
class TempClassEqualityComparer : IEqualityComparer<TempClass>
{
public bool Equals(TempClass x, TempClass y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
// For comparison check both combinations
return (x.One == y.One && x.Two == y.Two) || (x.One == y.Two && x.Two == y.One);
}
public int GetHashCode(TempClass x)
{
if (Object.ReferenceEquals(x, null)) return 0;
return x.One.GetHashCode() ^ x.Two.GetHashCode();
}
}
Then you can use this comparer in Distinct method:
var result = l.Distinct(new TempClassEqualityComparer());
Just order them before you create the key.
public string Key
{
get{
List<string> l = new List<string>{One, Two};
l = l.OrderBy(x => x).ToList();
return "Key_" + string.Join("_", l);
}
}

How do I find an object(s) by its hashcode?

Is there an easy way to dig in to an object and find a property or field by its hashcode? This could be a nested property or a value in a collection. The reason I ask is that I occasionally get WPF warnings that look like:
System.Windows.ResourceDictionary Warning: 9 : Resource not found;
ResourceKey='#FF000000'; ResourceKey.HashCode='51639504';
ResourceKey.Type='System.Windows.Media.SolidColorBrush'
The warning doesn't always appear and I'm having the hardest time tracking it down. I figure if I knew which object had that hashcode, I could get closer to fixing this. For instance, if I had this object:
var first = new { a = 1, b = 2, d = new { aa = 11, bb = 22 } };
and called this on it:
string str = FindHashCode(first, 22);
the result would be:
"Anon > d > bb.hashcode = 22"
or something similar. (I'm ignoring hashcode collisions for now)
Edit: Here's what I'll use based on #Alberto's answer. It searches both fields and properties whether public or non-public. It includes support for IEnumerables (Lists, Arrays, etc.) and more specifically IDictionaries. It also handles hashcode collisions. If two objects have the same hashcode, the StringBuilder will have a separate line for each object.
using System.Reflection;
static string FindHashCode(object o, int hashCode)
{
StringBuilder strb = new StringBuilder();
FindHashCode(o, hashCode, o.GetType().Name, strb);
return strb.ToString().Trim();
}
static void FindHashCode(object o, int hashCode, string path, StringBuilder strb)
{
if (o.GetHashCode() == hashCode)
{
strb.AppendLine(path + ".hashcode = " + hashCode);
}
foreach (var field in GetFieldInfo(o))
{
if (field.Item1 == null || object.ReferenceEquals(o, field.Item1))
continue;
Type type = field.Item1.GetType();
if (type.IsPrimitive)
{
if(field.Item1.GetHashCode() == hashCode)
strb.AppendLine(path + " > " + field.Item2 + ".hashcode = " + hashCode);
}
else
{
FindHashCode(field.Item1, hashCode, path + " > " + field.Item2, strb);
}
}
}
static IEnumerable<Tuple<object, string>> GetFieldInfo(object arg)
{
var ienum = arg as System.Collections.IEnumerable;
var idict = arg as System.Collections.IDictionary;
if (ienum == null && idict == null)
{
BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
Type type = arg.GetType();
var list = type.GetFields(bf).Select(s => new Tuple<object, string>(s.GetValue(arg), s.Name)).Concat(
type.GetProperties(bf).Select(s => new Tuple<object, string>(s.GetValue(arg, null), s.Name)));
foreach (var item in list)
{
yield return item;
}
}
else if (idict != null)
{
foreach (System.Collections.DictionaryEntry item in idict)
{
yield return new Tuple<object, string>(item.Key, string.Format("Dict[{0}].Key", item.Key));
yield return new Tuple<object, string>(item.Value, string.Format("Dict[{0}].Value", item.Key));
}
}
//note that dictionaries implement IEnumerable
else if (ienum != null && !(ienum is string))
{
int count = 0;
foreach (var item in ienum)
{
yield return new Tuple<object, string>(item, string.Format("this[{0}]", count));
count++;
}
}
}
Here an implementation that search recursively in an object graph for a property with a specific hashcode:
static string FindHashCode(object o, int hashCode)
{
return FindHashCodeImpl(o,hashCode, o.GetType().Name);
}
static string FindHashCodeImpl(object o, int hashCode, string partialPath)
{
var type = o.GetType();
var properties = type.GetProperties();
foreach (var property in properties)
{
var propValue = property.GetValue(o);
if (propValue.GetHashCode() == hashCode)
{
return partialPath + " > " + property.Name + ".hashcode = " + hashCode;
}
var path = FindHashCodeImpl(propValue, hashCode, partialPath + " > " + property.Name);
if (path != null)
{
return path;
}
}
return null;
}
Use it like:
var o = new { a = 1, b = 2, d = new { aa = 11, bb = 22 } };
var s = FindHashCode(o, 22); //Output "<>f__AnonymousType1`3 > d > bb.hashcode = 22"
You should extend it to search inside fields as well.
P.S I didn't test it for every scenario, but it should work...
There's no automatic way to search a graph of objects for a member whose hashcode matches a certain value. But if you know the structure (like a List) then you can go along and GetHashCode() for each one and return the matches (of which there could be many). I think you must have some concept of the data you're working with, some container such as a list or tree, right?
The Visual Studio debugger also lets you assign Object IDs to items in the watches so that you can know that two references are to the same item, in case that helps.
I think there are faster ways to find your bug.
Trace WPF System.Windows.ResourceDictionary warning Resource not found

Reflection help. Make a collection from a class based on its properties?

I need a little help. I am fairly new to reflection. We're using a 3rd party api and it returns a class called "AddressList". It has public properties within it literally called Address1, Address1Name, Address1Desc, Address2, Address2Name, Address2Desc, Address3, Address3Name, Address3Desc,... Address99, Address99Name, Address99Desc.. There are also a couple of other properties. I have a class called "SimpleAddress" that has just the 3 properties (Address, Name, Description). What I want to do is when I get the "AddressList" class returned, I would like to loop AddressDesc1... through AddressDesc99... and whichever ones are not null or empty, I would like to create an instance of "SimpleAddress", populate it's properties, and add it to a List... Can someone point me in the right direction? Obviously this would have been better if "AddressList" was some sort of collection, but unfortunately it is not. It is generated from a return string from a mainframe.
Thanks for any help,
~ck in San Diego
Ick. You could do something like this:
List<SimpleAddress> addresses = new List<SimpleAddress>();
string addressPropertyPattern = "Address{0}";
string namePropertyPattern = "Address{0}Name";
string descPropertyPattern = "Address{0}Desc";
for(int i = 1; i <= MAX_ADDRESS_NUMBER; i++)
{
System.Reflection.PropertyInfo addressProperty = typeof(AddressList).GetProperty(string.Format(addressPropertyPattern, i));
System.Reflection.PropertyInfo nameProperty = typeof(AddressList).GetProperty(string.Format(namePropertyPattern, i));
System.Reflection.PropertyInfo descProperty = typeof(AddressList).GetProperty(string.Format(descPropertyPattern, i));
SimpleAddress address = new SimpleAddress();
address.Address = (string)addressProperty.GetValue(yourAddressListObject, null);
address.Name = (string)nameProperty.GetValue(yourAddressListObject, null);
address.Description = (string)descProperty.GetValue(yourAddressListObject, null);
addresses.Add(address);
}
Start by getting the type of the class in question and invoke the GetProperties method.
PropertyInfo[] properties = myMainframeObject.GetType().GetProperties();
Each PropertyInfo has a Name attribute (a string) you can use to match against. Loop over all the properties, and write the code that creates a new instance of SimpleAddress.
Inside this loop, you can access your mainframe object and pull out the property values you need:
// imagine that in this case, 'p' is a PropertyInfo that represents Address2Name
var simpleAddress = new SimpleAddress();
simpleAddress.Name = p.GetValue(myMainframeObject, null);
(the null is never used for normal properties - it is intended for use with indexed properties).
You should be able to do something like:
List<SimpleAddress> CreateList(AddressList address)
{
List<SimpleAddress> values = new List<SimpleAddress>();
Type type = address.GetType();
for (int i=1;i<=99;++i)
{
string address = type.GetProperty("Address" + i.ToString()).GetValue(address,null).ToString();
string addressDesc = type.GetProperty("Address" + i.ToString() + "Desc").GetValue(address,null).ToString();
string addressName = type.GetProperty("Address" + i.ToString() + "Name").GetValue(address,null).ToString();
if (!string.IsNullOrEmpty(addressDesc) || !string.IsNullOrEmpty(addressName) || !string.IsNullOrEmpty(address) )
value.Add(new SimpleAddress(address,addressDesc,addressName));
}
return values;
}
Not tested (for obvious reasons), but something like:
List<SimpleAddress> newList = new List<SimpleAddress>();
AddressList list = ...
Type type = list.GetType();
PropertyInfo prop1, prop2, prop3;
int index = 1;
while((prop1 = type.GetProperty("Address" + index)) != null
&& (prop2 = type.GetProperty("Address" + index + "Name")) != null
&& (prop3 = type.GetProperty("Address" + index + "Desc")) != null) {
string addr = (string) prop1.GetValue(list, null),
name = (string) prop2.GetValue(list, null),
desc = (string) prop3.GetValue(list, null);
if(addr == null || name == null || desc == null) {
continue; // skip but continue
}
SimpleAddress newAddr = new SimpleAddress(addr, name, desc);
newList.Add(newAddr);
index++;
}
if you want to use linq
public static class MyTools
{
public static TReturn GetValue<TReturn>(this object input,
string propertyName)
{
if (input == null)
return default(TReturn);
var pi = input.GetType().GetProperty(propertyName);
if (pi == null)
return default(TReturn);
var val = pi.GetValue(input, null);
return (TReturn)(val == null ? default(TReturn) : val);
}
public static string GetString(this object input, string propertyName)
{
return input.GetValue<string>(propertyName);
}
public static List<SimpleAddress> GetAddress(this MyObject input)
{
return (
from i in Enumerable.Range(1, 2)
let address = input.GetString("Address" + i.ToString())
let name = input.GetString("Address" + i.ToString() + "Name")
let desc = input.GetString("Address" + i.ToString() + "Desc")
select new SimpleAddress() { Address = address,
Name = name,
Description = desc }
).ToList();
}
}
var addrList = new AddressList
{
Address1Name = "ABC",
Address1Desc = "DEF",
Address1 = "GHI",
Address3Name = "X",
Address3Desc = "Y",
Address3 = "Z"
};
var addresses =
from i in Enumerable.Range(1, 99)
let desc = typeof(AddressList).GetProperty(string.Format("Address{0}Desc", i)).GetValue(addrList, null) as string
let name = typeof(AddressList).GetProperty(string.Format("Address{0}Name", i)).GetValue(addrList, null) as string
let address = typeof(AddressList).GetProperty(string.Format("Address{0}", i)).GetValue(addrList, null) as string
where !string.IsNullOrEmpty(address)
select new SimpleAddress
{
Name = name,
Description = desc,
Address = address
};

Categories