Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# FOREACH on multiple LIST<> types

Tags:

c#

foreach

list

Hi everyone and thanks for looking.

I'm not thinking this is possible, but I'd like to do an identical FOREACH through multiple returned LIST<> types without having to cut and paste the code 4 times. All properties of the dto2, dto3, dto4, and dto5 lists returned are the same, except for the DataValue, which is a different data type for each (int, varchar, bool, etc.)

var dto2 = rd.EngDetailBitsList(dto.EngId);
var dto3 = rd.EngDetailDateTimesList(dto.EngId);
var dto4 = rd.EngDetailVarCharsList(dto.EngId);
var dto5 = rd.EngDetailVarCharMaxesList(dto.EngId);

foreach (var x in dto2)
{
    var propertyInfo = dto.GetType().GetProperty(x.ShortDescript,
           BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
    if (propertyInfo != null)
    { 
        propertyInfo.SetValue(dto, x.DataValue);
    }
}

foreach (var x in dto3)
{
    var propertyInfo = dto.GetType().GetProperty(x.ShortDescript,
           BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
    if (propertyInfo != null)
    {
        propertyInfo.SetValue(dto, x.DataValue);
    }
}

foreach (var x in dto4)
{
    var propertyInfo = dto.GetType().GetProperty(x.ShortDescript,
           BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
    if (propertyInfo != null)
    {
        propertyInfo.SetValue(dto, x.DataValue);
    }
}

foreach (var x in dto5)
{
    var propertyInfo = dto.GetType().GetProperty(x.ShortDescript,
           BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
    if (propertyInfo != null)
    {
        propertyInfo.SetValue(dto, x.DataValue);
    }
}
like image 651
Brian Leidel Avatar asked Jul 16 '26 11:07

Brian Leidel


1 Answers

There are two ways of solving that:

  1. Assuming all dto2, dto3, dto4 and dto5 are collections of some type T that implements common interface with ShortDescript and DataValue properties declared on it.

    var dto2 = rd.EngDetailBitsList(dto.EngId);
    var dto3 = rd.EngDetailDateTimesList(dto.EngId);
    var dto4 = rd.EngDetailVarCharsList(dto.EngId);
    var dto5 = rd.EngDetailVarCharMaxesList(dto.EngId);
    
    var source = dto2.Cast<MyInterface>
                     .Concat(dto3.Cast<MyInterface>)
                     .Concat(dto4.Cast<MyInterface>)
                     .Concat(dto4.Cast<MyInterface>);
    
    
    var dtoType = dto.GetType();
    foreach (var x in source)
    {
        var propertyInfo = dtoType.GetProperty(x.ShortDescript,
               BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
        if (propertyInfo != null)
        {
            propertyInfo.SetValue(dto, x.DataValue);
        }
    }
    
  2. Without common interface you can use dynamic:

    var dto2 = rd.EngDetailBitsList(dto.EngId);
    var dto3 = rd.EngDetailDateTimesList(dto.EngId);
    var dto4 = rd.EngDetailVarCharsList(dto.EngId);
    var dto5 = rd.EngDetailVarCharMaxesList(dto.EngId);
    
    var source = dto2.Cast<dynamic>
                     .Concat(dto3.Cast<dynamic>)
                     .Concat(dto4.Cast<dynamic>)
                     .Concat(dto4.Cast<dynamic>);
    
    dto.GetType() 
    foreach (var x in source)
    {
        var propertyInfo = dtoType.GetProperty(x.ShortDescript,
               BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
        if (propertyInfo != null)
        {
            propertyInfo.SetValue(dto, x.DataValue);
        }
    }
    

    This will make ShortDescript and DataValue properties to be resolved at runtime and you'll get an exception when there is no such a property on actual type.

like image 176
MarcinJuraszek Avatar answered Jul 18 '26 01:07

MarcinJuraszek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!