Как конвертировать C # обнуляемый int в int

484

Как я могу преобразовать обнуляемый intв int? Предположим, у меня есть 2 типа int, как показано ниже:

int? v1;  
int v2; 

Я хочу присвоить v1значение v2. v2 = v1;вызовет ошибку. Как мне конвертировать v1в v2?

KentZhou
источник
Каково желаемое поведение, когда v1есть null?
Соломон Уцко

Ответы:

637

Все остальные ответы пока верны; Я просто хотел добавить еще один, который немного чище:

v2 = v1 ?? default(int);

Любой Nullable<T>является неявно конвертируемым к своему T, ПРЕДОСТАВЛЯЯ, что все вычисляемое выражение никогда не может привести к нулевому назначению ValueType. Таким образом, оператор с нулевым слиянием ??является просто синтаксическим сахаром для троичного оператора:

v2 = v1 == null ? default(int) : v1;

... который в свою очередь является синтаксическим сахаром для if / else:

if(v1==null)
   v2 = default(int);
else
   v2 = v1;

Кроме того, начиная с .NET 4.0, Nullable<T>есть метод «GetValueOrDefault ()», который является нулевым безопасным геттером, который в основном выполняет объединение нулей, как показано выше, так что это тоже работает:

v2 = v1.GetValueOrDefault();
Keiths
источник
4
Является ли на default(int)самом деле нужно? Что не так с простым 0?
Коул Джонсон
4
Это будет работать для этого примера, но в общем случае рекомендуется использовать defaultтам, где это необходимо. Ноль не всегда допустим в качестве значения, тем более, по умолчанию, поэтому, если вы замените intего универсальным, Tвы обнаружите, что мой код работает, а ноль - нет. В некоторых будущих версиях фреймворка defaultтакже может стать перегруженным; если и когда это произойдет, код, использующий default, будет легко использовать преимущества, в то время как явные нулевые или нулевые назначения должны быть изменены.
KeithS
5
Это должно подняться до вершины: .NET 4.0, Nullable <T> имеет «GetValueOrDefault ()»
RandomHandle
Спасибо, что вернулись, чтобы отредактировать его с помощью GetValueOrDefault!
CindyH
Вы можете быть осторожны с DateTime при использовании по умолчанию. Это может вставить дату по умолчанию вместо пустой.
Ранчо Камаль
168

Нравится,

if(v1.HasValue)
   v2=v1.Value
Сринивас Редди Татиарти
источник
92

Вы можете использовать свойство Value для назначения.

v2 = v1.Value;
e36M3
источник
8
Кроме того, если вы не уверены, содержит ли v1 значение null, вы можете использовать оператор объединения нулей, чтобы установить запасное значение. Например, v2 = v1 ?? 0;
Арьен
12
И обязательно проверьте v1.HasValueсначала.
Yuck
3
MSDN говорит, что это будет исключение, если v1есть null. На мой взгляд, это не правильный ответ.
ventiseis
6
@ventiseis Я думаю, что это желательное поведение - я удивлен, что многие другие ответы в порядке с тихим преобразованием нулевого в 0. Если вы присваиваете необнуляемый тип ненулевому типу, вы должны быть уверены, что значение на самом деле не равно нулю. ОП не сказал: «Я хочу назначить v1 для v2 или 0, если v1 равен нулю», но это, как все, казалось, предполагали
Майкл Мрозек
82

Все, что тебе нужно..

v2= v1.GetValueOrDefault();
звезда
источник
49

Если вы знаете, что v1имеет значение, вы можете использовать Valueсвойство:

v2 = v1.Value;

При использовании GetValueOrDefaultметода присваивается значение, если оно есть, в противном случае используется значение по умолчанию для типа или заданное вами значение по умолчанию:

v2 = v1.GetValueOrDefault(); // assigns zero if v1 has no value

v2 = v1.GetValueOrDefault(-1); // assigns -1 if v1 has no value

Вы можете использовать HasValueсвойство, чтобы проверить, v1имеет ли значение:

if (v1.HasValue) {
  v2 = v1.Value;
}

Существует также языковая поддержка GetValueOrDefault(T)метода:

v2 = v1 ?? -1;
Guffa
источник
Вы не должны использовать значение без предварительной проверки, чтобы увидеть, есть ли значение. Использовать ?? оператор вместо.
Питер
45

Вы не можете сделать это, если v1 является нулем, но вы можете проверить с оператором.

v2 = v1 ?? 0;
Артуро Мартинес
источник
28

GetValueOrDefault()

получает значение объекта. Если это ноль, это возвращает значение по умолчанию int, которое является 0.

Пример:

v2= v1.GetValueOrDefault();

Аникет Шарма
источник
21

Если значение по умолчанию для данного типа является приемлемым результатом:

if (v1.HasValue)
    v2 = v1.GetValueOrDefault();

Если вам нужно другое значение по умолчанию, когда результат не определен:

v2 = v1.GetValueOrDefault(255);    // or any valid value for int in place of 255

Если вы просто хотите вернуть значение (независимо от того, произошел сбой или нет):

v2 = v1.GetValueOrDefault();


.NET 4.7.2 .: GetValueOrDefault()возвращает значение поля без какой-либо проверки.

GrzegorzF
источник
15

Насколько мне известно, лучшим решением является использование GetValueOrDefault()метода.

v2 = v1.GetValueOrDefault();
Масуд Дарвишян
источник
этот был наиболее полезным для меня
Liakat
11

Преобразование Int Nullable в Int может быть сделано так:

v2=(int)v1;
Кришна Шиднекоппа
источник
9
Если v1 является нулем, это вызовет InvalidOperationException.
MungeWrath
10

это возможно с v2 = Convert.ToInt32(v1);

оборот
источник
Это будет работать технически, но другие методы, такие как HasValue / Value или GetValueOrDefault, работают намного эффективнее.
Брэндон Баркли
9

Вы могли бы сделать

v2 = v1.HasValue ? v1.Value : v2;
Пожарная панда
источник
9

Простое преобразование между v1и v2невозможно, поскольку v1имеет большую область значений, чем v2. Это все v1может держать плюс nullсостояние. Для преобразования вам необходимо явно указать, какое значение intбудет использоваться для отображения nullсостояния. Самый простой способ сделать это - ??оператор

v2 = v1 ?? 0;  // maps null of v1 to 0

Это также может быть сделано в длинной форме

int v2;
if (v1.HasValue) {
  v2 = v1.Value;
} else {
  v2 = 0;
}
JaredPar
источник
9

В зависимости от контекста использования вы можете использовать функцию сопоставления с образцом в C # 7:

int? v1 = 100;
if (v1 is int v2)
{
    Console.WriteLine($"I'm not nullable anymore: {v2}");
}

РЕДАКТИРОВАТЬ:

Поскольку некоторые люди отказываются от голосования, не оставляя объяснений, я хотел бы добавить некоторые подробности, чтобы объяснить обоснование включения этого в качестве жизнеспособного решения.

  • Сопоставление с образцом в C # 7 теперь позволяет нам проверять тип значения и приводить его неявно. В приведенном выше фрагменте условие if будет проходить только в том случае, если значение, хранимое в v1, совместимо с типом для типа for v2, которым в данном случае является int. Из этого следует, что когда значение для v1is null, условие if не будет выполнено, поскольку null не может быть назначен для int. Вернее, nullне является int.

  • Я хотел бы подчеркнуть, что это решение не всегда может быть оптимальным выбором. Как я предполагаю, я считаю, что это будет зависеть от точного контекста использования разработчика. Если у вас уже есть int?и вы хотите условно воздействовать на его значение, если-и-только-если назначенное значение не равно нулю (это единственный раз, когда безопасно преобразовать обнуляемое int в обычное int без потери информации), тогда сопоставление с образцом, пожалуй, один из самых кратких способов сделать это.

Николас Миллер
источник
К сожалению, необходимо ввести новое имя переменной, но это лучшее (самое безопасное) решение, если нет значения по умолчанию, потому что нет риска случайного рефакторинга ваших HasValueчеков.
Minexew
Я просто не вижу никакого преимущества этого метода перед v1.HasValue в качестве проверки, а затем v1.Value для доступа к базовому значению. Я бы не стал опровергать это, но я думаю, что эта проблема уже решена, и новая методика не добавляет ясности этой проблеме. Я также оценил его на 8-9% медленнее.
Брэндон Баркли
Спасибо за сравнение, это приятно знать! В любом случае, если посмотреть, разница в лучшем случае незначительна (я полагаю, если вы не сделаете это в какой-то критически важной области). Я смотрю на это как на более "сжатое" или, возможно, "идиоматическое", поскольку оно опирается на синтаксические сахара, запеченные в языке вместо API. Это немного субъективно, но, возможно, это «более ремонтопригодно». Хотя на самом деле мне нравится этот подход больше, чем полагаться на значение по умолчанию, как предлагают многие другие ответы.
Николас Миллер
3

Это присвоит значение v1для v2если оно не равно нулю, в противном случае он будет принимать значения по умолчанию , как ноль.

v2=v1??0

Или ниже другой способ написать это.

v2 = v1.HasValue?v1:0
Сагар
источник
-1
 int v2= Int32.Parse(v1.ToString());
Мохаммад Кавизи
источник
5
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, почему и / или как этот код отвечает на вопрос, повышает его долгосрочную ценность.
Xiawi
1
Лучше использовать способ «лучшей практики», чтобы развернуть дополнительные функции, а не использовать закулисные трюки. См. Docs.microsoft.com/en-us/dotnet/csharp/language-reference/… для справки
lorg
При ответе на восьмилетний вопрос с пятнадцатью существующими ответами важно объяснить, каков новый аспект вопроса, к которому относится ваш ответ, и отметить, изменился ли ответ с течением времени. Код только ответы почти всегда можно улучшить, добавив некоторые объяснения.
Джейсон Аллер