简体   繁体   English

泛型类型的函数:返回一个不可为空的值

[英]Generic typed function: return a non-nullable value

I wrote this trivial utility function: 我写了这个琐碎的实用函数:

public static T isNull<T>(T? v, T d)
{
    return v == null ? d : v.Value;
}

the purpose is to avoid annoying task like check for a member to be null, very common in reading a linq recordset. 目的是避免令人讨厌的任务,例如检查成员是否为空,这在读取linq记录集时很常见。 The problem is that it's throwing this error: 问题是它引发了以下错误:

The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable< T>' 为了在通用类型或方法“ System.Nullable <T>”中将其用作参数“ T”,类型“ T”必须为非空值类型

The error seems legit, anyway I wish I can do something like this: 该错误似乎合法,无论如何我希望我可以做这样的事情:

int? myField = record.myField;
int  myValue = isNull(myField, 0);

instead of: 代替:

int? myField = record.myField;
int  myValue = myField == null ? 0 : myField.Value;

I feel like I'm missing some c# basic knowledge. 我觉得我缺少一些C#基本知识。 Does exist a way to accomplish my task? 是否存在完成任务的方法?

Generic constraints can be used on generic functions to limit the types that are permitted to be used to certain subsets, and this opens up possibilities for how you might use those types inside your method or class. 通用约束可用于通用函数,以将允许使用的类型限制为某些子集,这为您如何在方法或类中使用这些类型提供了可能性。

In this case, you can apply a constraint to T that limits it to a struct to resolve your specific compiler error. 在这种情况下,你可以申请成为制约T ,是限制了一个struct ,以解决您的具体编译器错误。

public static T IsNull<T>(T? v, T d) where T : struct
{
    return v == null ? d : v.Value;
}

However, another answer does correctly point out that you could opt to use the null coalescing operator ?? 但是,另一个答案确实正确地指出您可以选择使用空合并运算符?? in this particular situation. 在这种特殊情况下。

这称为空合并,并且有一个内置的运算符可以做到这一点:

int myValue = record.myField ?? 0

While the other answers are good, presumably you'd like to write your method so it would work with both reference and value types. 尽管其他答案都不错,但是大概您希望编写您的方法,使其可以同时用于引用和值类型。 You can accomplish that by having two overloads, both with generic constraints. 您可以通过两个都有通用约束的重载来实现。

public static T IsNull<T>(T v, T d) where T : class
{
    return v ?? d;
}

public static T IsNull<T>(T? v, T d) where T : struct
{
    return v.HasValue ? v.Value : d;
}

NOTE: Calling IsNull with a value type other than Nullable<T> will still not compile. 注意:使用非Nullable<T>以外的其他值类型调用IsNull仍不会编译。 eg 例如

string myString = ...
Console.WriteLine(IsNull(myString, "foo"))            // works

object myObject = ...
Console.WriteLine(IsNull(myMyObject, new object()))   // works

DateTime? myDateTime = ...
Console.WriteLine(IsNull(myDateTme, DateTme.Now))     // works

int? myInt1 = ...
Console.WriteLine(IsNull(myInt1, DateTme.Now))        // works

int myInt2 = ...
Console.WriteLine(IsNull(myInt2, DateTme.Now))        // <-- compiler error

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM