0

I would like to know how I can get all int value in a model LINQ. Example : My Model

public class MyClass
    {
        public string Title { get; set; }
        public string Name { get; set; }
        public int a{ get; set; }
        public int b{ get; set; }
        public int c{ get; set; }
    }

And I want to get only the int value to do for example a Sum with linq (a+b+c):

        var sumOfInt= Result.Where(t => t.GetType== int ).Sum()

Thanks in advance for your help.

Nico78000
  • 27
  • 3
  • 2
    Is `Result` a single instance of `MyClass` or a sequence of instances of `MyClass`? You'd need to use reflection to achieve that. But maybe if you add some context and explain what you are _actually_ trying to achieve, there maybe a better overall design. – René Vogt Mar 22 '17 at 13:38
  • Just to be sure. You want to get the sum of all int values of one instance ot the sum of all int values of many instances? – Mighty Badaboom Mar 22 '17 at 13:38
  • 2
    That's a strange request. Why don't you add a method to your class that generates that sum? LINQ works with collections while you want to read arbitrary properties. That's a job for Reflection. The resulting code would be rather ugly and fragile. For example, if your class had an integer `Id` property it would also be included in the sum – Panagiotis Kanavos Mar 22 '17 at 13:39
  • 3
    From @VladimirArustamian: I'm pretty sure you don't need to solve that task. Find a better way to design your application. What is the actual problem you are trying to solve? – Panagiotis Kanavos Mar 22 '17 at 13:40
  • What are you trying to do? What is the *actual* problem you are trying to solve? Most likely there are other, better ways to do it – Panagiotis Kanavos Mar 22 '17 at 13:46

5 Answers5

7

First, let me say that this does not sound like a good idea. If you later add an ID property to your model, do you really want your code to automatically add its value to your sum?

That said, should you happen to have very good reasons for doing this, you can perform the following steps:

Community
  • 1
  • 1
Heinzi
  • 167,459
  • 57
  • 363
  • 519
3

If you want to sum up a, b, c values from MyClass you can use Reflection and Linq:

  using System.Linq;
  using System.Reflection;
  ...   

  MyClass source = ...

  var sum = source
    .GetType()
    .GetProperties(BindingFlags.Instance |
                   BindingFlags.Public | 
                   BindingFlags.NonPublic) // you may want not to read non-public props
    .Where(p => p.CanRead && p.PropertyType == typeof(int))
    .Sum(p => (int) p.GetValue(source));
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • This would work as long as there aren't any ID properties. The OP should explain what the actual goal is – Panagiotis Kanavos Mar 22 '17 at 13:45
  • @Panagiotis Kanavos: I agree "...get all int value.." sounds very suspecious (shall, say *private* properties be included into the sum, whay shall we sum up integer *Ids* if any are in the class..) – Dmitry Bychenko Mar 22 '17 at 13:47
2

you can to it like this:

MyClass cls = new MyClass();
cls.a = 10;
cls.b = 20;
cls.c = 30;
int sum = cls.GetType()
    .GetProperties()
    .Where(x => x.PropertyType == typeof(int))
    .Sum(x => (int)x.GetValue(cls));
Nino
  • 6,931
  • 2
  • 27
  • 42
1

Result.SelectMany(r => new[] { r.a, r.b, r.c }).Sum()

But it's unclear what exactly do you need? Do you need a code which can (through Reflection) get all int properties of MyClass? Or you just need to flatten all of them into single IEnumerable?

oryol
  • 5,178
  • 2
  • 23
  • 18
  • 2
    Whoever downvoted this should consider that this is the only *sensible* solution given the OP's question. Using reflection would result in ugly and slow code. The OP should rethink the design – Panagiotis Kanavos Mar 22 '17 at 13:42
  • Might as well be `Select(r => r.a + r.b + r.c).Sum()`. No need to create a bunch of unneeded intermediate arrays. – juharr Mar 22 '17 at 13:45
  • @juharr even better, `Select(r=>r.Periphery()).Sum()` where `Periphery()=>a+b+c;`. – Panagiotis Kanavos Mar 22 '17 at 13:47
  • @PanagiotisKanavos Also a good approach, but I definitely agree that if you find that you want to use reflection then 9 times out of 10 you should probably rethink your design. – juharr Mar 22 '17 at 13:52
  • @juharr every answerer and commenter to this question agrees – Panagiotis Kanavos Mar 22 '17 at 14:00
0

If you want do it with linq you can use Expression Another answers provide details and examples for this way. But If you want dynamically get all properties with in type -The simply way is Reflection

Note that Reflection hits by performance and usually we should use this ways only if another approach is impossible. That is why i do not suggest use reflection. Instead of it i provide example with helper method inside your class

    class Model
    {

        private Dictionary<string, int> fieldsForSum = new Dictionary<string, int>();
        private int age;
        private int year;

        public int Age
        {
            get { return age; }
            set
            {
                bool isContain = fieldsForSum.ContainsKey(nameof(age));
                if (isContain)
                    fieldsForSum[nameof(age)] = value;
                else
                    fieldsForSum.Add(nameof(age), value);
                age = value;
            }
        }

        public int Year
        {
            get { return year; }
            set
            {

                bool isContain = fieldsForSum.ContainsKey(nameof(year));
                if (isContain)
                    fieldsForSum[nameof(year)] = value;
                else
                    fieldsForSum.Add(nameof(year), value);
                year = value;
            }
        }

        public int CalcIntFields()
        {
            return fieldsForSum.Values.Sum();
        }
    } 

and example of usage

        var m = new Model
        {
            Age = 4,
            Year = 3
        };
        var sum = m.CalcIntFields();//7
        m.Year = 1;
        sum = m.CalcIntFields(); //5
Artsiom Che
  • 122
  • 8
  • Reflection *adds* a lot of overhead. Just check all answers that use expressions like `r => r.a + r.b + r.c` and those that use reflection. – Panagiotis Kanavos Mar 22 '17 at 14:00
  • you don't understand me. Of course reflection hits by preformance. It's clear for everyone. I mean that **implementation** with using reflection is more easy that Expression way. and I updated post for clarify – Artsiom Che Mar 22 '17 at 14:13
  • That's what I meant also. `r => r.a + r.b + r.c` *is* an Expression. The question you linked to asks something *completely* different - how to generate queries dynamically. For which, you don't need an expression tree most of the time – Panagiotis Kanavos Mar 22 '17 at 14:15
  • In any case, this should be a comment, not an answer. You do mention reflection but don't provide more information or a solution, as the other questions here – Panagiotis Kanavos Mar 22 '17 at 14:16