Как работает GetValueOrDefault?
я отвечаю за поставщика LINQ, который выполняет некоторую оценку кода C# во время выполнения. В качестве примера:
int? thing = null;
accessor.Product.Where(p => p.anInt == thing.GetValueOrDefault(-1))
В настоящее время приведенный выше код не работает с моим поставщиком LINQ из-за thing
быть null.
пока я работаю с C# в течение длительного времени, я не знаю, как реализован GetValueOrDefault и, следовательно, как я должен это решить.
Итак, мой вопрос: как GetValueOrDefault
работа в том случае, если экземпляр, на котором он вызывается имеет значение null? Почему не NullReferenceException
кинули?
следовать на вопрос: как я должен пойти о репликации вызова GetValueOrDefault
используя отражение, учитывая, что мне нужно обрабатывать нулевые значения.
3 ответов
thing
не null
. Поскольку структуры не могут быть null
, Так что Nullable<int>
не может быть null
.
вещь... это просто магия компилятора. Вы думаю это null
. На самом деле,HasValue
расположен в false
.
если вы называете GetValueOrDefault
он проверяет, если HasValue
is true
или false
:
public T GetValueOrDefault(T defaultValue)
{
return HasValue ? value : defaultValue;
}
A NullReferenceException
не выбрасывается, потому что нет ссылки. The GetValueOrDefault
является методом в Nullable<T>
structure, поэтому вы используете его для типа значения, а не ссылочного типа.
на GetValueOrDefault(T)
метод просто реализуется следующим образом:
public T GetValueOrDefault(T defaultValue) {
return HasValue ? value : defaultValue;
}
Итак, чтобы воспроизвести поведение, вам просто нужно проверить HasValue
свойства, чтобы увидеть, какое значение использовать.
Я думаю, что ваш провайдер работал неправильно. Я сделал простой тест и он правильно работал.
using System;
using System.Linq;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
var products = new Product[] {
new Product(){ Name = "Product 1", Quantity = 1 },
new Product(){ Name = "Product 2", Quantity = 2 },
new Product(){ Name = "Product -1", Quantity = -1 },
new Product(){ Name = "Product 3", Quantity = 3 },
new Product(){ Name = "Product 4", Quantity = 4 }
};
int? myInt = null;
foreach (var prod in products.Where(p => p.Quantity == myInt.GetValueOrDefault(-1)))
{
Console.WriteLine($"{prod.Name} - {prod.Quantity}");
}
Console.ReadKey();
}
}
public class Product
{
public string Name { get; set; }
public int Quantity { get; set; }
}
}
Она производит как выход: продукт -1 - -1