Как работает 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