¿Hay una forma más elegante de agregar ints nullables?


Necesito añadir numerosas variables de tipo nullable int. Utilicé el operador coalescente nulo para reducirlo a una variable por línea, pero tengo la sensación de que hay una forma más concisa de hacer esto, por ejemplo, no puedo encadenar estas sentencias juntas de alguna manera, lo he visto antes en otro código.

using System;

namespace TestNullInts
{
    class Program
    {
        static void Main(string[] args)
        {
            int? sum1 = 1;
            int? sum2 = null;
            int? sum3 = 3;

            //int total = sum1 + sum2 + sum3;
            //int total = sum1.Value + sum2.Value + sum3.Value;

            int total = 0;
            total = total + sum1 ?? total;
            total = total + sum2 ?? total;
            total = total + sum3 ?? total;

            Console.WriteLine(total);
            Console.ReadLine();
        }
    }
}
Author: Edward Tanguay, 2010-08-30

8 answers

var nums = new int?[] {1, null, 3};
var total = nums.Sum();

Esto se basa en la IEnumerable<Nullable<Int32>>sobrecarga de la Enumerable.Sum el Método, que se comporta como cabría esperar.

Si tiene un valor predeterminado que no es igual a cero, puede hacer:

var total = nums.Sum(i => i.GetValueOrDefault(myDefaultValue));

O la abreviatura:

var total = nums.Sum(i => i ?? myDefaultValue);

 46
Author: Ani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-30 10:43:21
total += sum1.GetValueOrDefault();

Etc.

 20
Author: Albin Sunnanbo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-30 10:09:21

Solo para responder la pregunta más directamente:

int total = (sum1 ?? 0) + (sum2 ?? 0) + (sum3 ?? 0);

De esta manera las declaraciones se "encadenan" juntas como se les pide usando un +

 10
Author: user230910,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-04 09:02:55
List<Nullable<int>> numbers = new List<Nullable<int>>();
numbers.Add(sum1);
numbers.Add(sum2);
numbers.Add(sum3);

int total = 0;
numbers.ForEach(n => total += n ?? 0);

De esta manera puede tener tantos valores como desee.

 2
Author: devnull,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-30 10:16:52

Cómo sobre el método helper -

static int Sum(params int?[] values)
{
  int total = 0;
  for(var i=0; i<values.length; i++) {
     total += values[i] ?? 0;
  }
  return total;
}

IMO, no es muy elegante, pero al menos agrega tantos números como quieras de una sola vez.

total = Helper.Sum(sum1, sum2, sum3, ...);
 1
Author: VinayC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-30 10:12:34

Usted podría hacer

total += sum1 ?? 0;
total += sum2 ?? 0;
total += sum3 ?? 0;
 1
Author: Brian Rasmussen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-30 10:14:35

¿Qué tal simplemente sustituir (sumX ?? 0) por sumX en la expresión no nullable correspondiente?

using System; 

namespace TestNullInts 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            int? sum1 = 1; 
            int? sum2 = null; 
            int? sum3 = 3; 

            int total = 0; 
            total += (sum1 ?? 0) + (sum2 ?? 0) + (sum3 ?? 0); 

            Console.WriteLine(total); 
            Console.ReadLine(); 
        } 
    } 
} 
 1
Author: Martin Liversage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-30 10:25:24

El uso más simple y elegante de LINQ:

var list = new List<Nullable<int>> { 1, 2, null, 3 };
var sum = list.Sum(s => s ?? 0);
Console.WriteLine(sum);

Necesita el coalesce AFAIK para asegurarse de que el resultado no sea nullable.

 0
Author: ChrisSmith..zzZZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-30 10:27:23