How to select all values ​​of an object property in a list of typed objects in .Net using C #

Wow, how do I explain this ... Probably a simple question, but my mind is on fire.

Suppose I have this class:

public class NestedObject { public string NestedName { get; set; } public int NestedIntValue { get; set; } public decimal NestedDecimalValue { get; set; } } public class SomeBigExternalDTO { public int Id { get; set; } public int UserId { get; set; } public int SomeIntValue { get; set; } public long SomeLongValue { get; set; } public decimal SomeDecimalValue { get; set; } public string SomeStringValue { get; set; } public NestedObject SomeNestedObject { get; set; } // ... thousands more of these properties... inherited code } 

And the class I would like to populate is here:

 public class MyResult { public int UserId { get; set; } // user id from above object public string ResultValue { get; set; } // one of the value fields from above with .ToString() executed on it } 

I would like to create a helper to return property values ​​(cross section is the best way to describe it, I think) of all instances in the list of this object:

 var foo = new List<SomeBigExternalDTO>(); foo = GetMyListOfSomeBigExternalDTO(); public static List<MyResult> AwesomeHelper(List<SomeBigExternalDTO> input, SearchableProperty thePropertyIWant) { // some magic needs to happen here... } 

The hard part here is that I want to dynamically pass the property based on the link selector (I don't know how to do this):

 var output = AwesomeHelper(GetMyListOfSomeBigExternalDTO(), x => x.SomeIntValue); var output2 = AwesomeHelper(GetMyListOfSomeBigExternalDTO(), x => x.SomeNestedObject.NestedIntValue); 

And this should return a list of MyResult objects with UserId and SomeIntValue.ToString () corresponding to each element in the input list.

Wow, I really hope this makes sense. Please let me know if this is not clear. I will tell in more detail. I really hope this is something baked in libraries that I forgot.

Any ideas on how I would accomplish this?

+3
source share
2 answers

Often when you try to create a general list operator, you end up redefining what LINQ already offers.

Here's the LINQ code for what you need (without the AwesomeHelper function):

 var results = list.Select(l => new MyResult() { UserId = l.UserId, ResultValue = l.SomeDecimalValue.ToString() }).ToList(); 

Pretty simple.

If you want to have the AwesomeHelper function for your request, it looks like this:

 public static List<MyResult> AwesomeHelper( List<SomeBigExternalDTO> input, Func<SomeBigExternalDTO, object> selector) { return input .Select(i => new MyResult() { UserId = i.UserId, ResultValue = selector(i).ToString() }) .ToList(); } 

And the calling code looks like this:

 var results = AwesomeHelper(list, x => x.SomeIntValue); 

For me, this is now less than the LINQ option. Now there is some magic, and it’s hard to understand that.

I have an alternative that will give you the best of both worlds.

First, define an extension method called ToMyResult that maps one instance of SomeBigExternalDTO to one MyResult with a field selector, for example:

 public static class AwesomeHelperEx { public static MyResult ToMyResult( this SomeBigExternalDTO input, Func<SomeBigExternalDTO, object> selector) { return new MyResult() { UserId = input.UserId, ResultValue = selector(input).ToString() }; } } 

Now the calling code is crystal clear, flexible and concise. There he is:

 var results = ( from item in list select item.ToMyResult(x => x.SomeLongValue) ).ToList(); 

Hope this helps.

+2
source

You can implement it as an extension method:

 public static IEnumerable<MyResult> AwesomeHelper(this IEnumerable<SomeBigExternalDTO> input, Func<SomeBigExternalDTO, int> intMapper) { foreach (var item in input) yield return new MyResult() { UserId = item.UserId, ResultValue = intMapper(item) }; } 

Now you can use it as follows:

 var output = GetMyListOfSomeBigExternalDTO().AwesomeHelper( x => x.SomeIntValue); var output2 = GetMyListOfSomeBigExternalDTO().AwesomeHelper( x => x.SomeNestedObject.NestedIntValue); 

Having said that - don't do it - it looks like you are inventing what Linq already offers you, you can do the same using only Linq :

 var output = GetMyListOfSomeBigExternalDTO().Select( x=> new MyResult() { UserId = item.UserId, ResultValue = x.SomeIntValue }); var output2 = GetMyListOfSomeBigExternalDTO().Select( x=> new MyResult() { UserId = item.UserId, ResultValue = x.SomeNestedObject.NestedIntValue }); 
+3
source

Source: https://habr.com/ru/post/897200/


All Articles