我想做这样的事情:
myYear = record.GetValueOrNull<int?>("myYear"),
Run Code Online (Sandbox Code Playgroud)
请注意可空类型作为通用参数.
由于该GetValueOrNull函数可以返回null,我的第一次尝试是这样的:
public static T GetValueOrNull<T>(this DbDataRecord reader, string columnName)
where T : class
{
object columnValue = reader[columnName];
if (!(columnValue is DBNull))
{
return (T)columnValue;
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
但我现在得到的错误是:
类型'int?' 必须是引用类型才能在泛型类型或方法中将其用作参数"T"
对!Nullable<int>是一个struct!所以我尝试将类约束更改为struct约束(并且副作用不能再返回null):
public static T GetValueOrNull<T>(this DbDataRecord reader, string columnName)
where T : struct
Run Code Online (Sandbox Code Playgroud)
现在任务:
myYear = record.GetValueOrNull<int?>("myYear");
Run Code Online (Sandbox Code Playgroud)
给出以下错误:
类型'int?' 必须是非可空值类型才能在泛型类型或方法中将其用作参数"T"
是否可以将可空类型指定为通用参数?
Java 1.8正在接收Optional类,它允许我们明确说明方法何时可以返回空值并"强制"其使用者isPresent()在使用它之前验证它是否为null().
我看到C#有Nullable,它做了类似的事情,但有基本类型.它似乎用于数据库查询,以区分值何时存在,并且当它不存在时为0并且为空.
但似乎C#的Nullable不适用于对象,仅适用于基本类型,而Java的Optional仅适用于对象而不适用于基本类型.
在C#中是否有Nullable/Optional类,这迫使我们在提取和使用它之前测试对象是否存在?
我知道default(bool?)回报null:
var msg = default(bool?) is null ?
"default(bool?) is NULL":
"default(bool?) is NOT NULL";
// msg == "default(bool?) is NULL"
Run Code Online (Sandbox Code Playgroud)
然而,当处理泛型类型参数时,它会导致令人困惑的结果。
考虑如下通用方法:
static TValue? GetProcItem<TValue>(IDictionary<string, JToken> cache, string key)
{
if(cache.TryGetValue(key, out var jtoken))
{
var value = jtoken.ToObject<TValue>();
return value;
}
// if the key does not exist
TValue? ret = default(TValue?);
return ret;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码返回default(TValue?)不适用于bool指定的泛型类型:
var cache = new Dictionary<string, JToken>();
// the compiler infers that xBool is a …Run Code Online (Sandbox Code Playgroud) 我正在将一堆代码从VB转换为C#,而我正在遇到一个方法的问题.这个VB方法效果很好:
Public Function FindItem(ByVal p_propertyName As String, ByVal p_value As Object) As T
Dim index As Int32
index = FindIndex(p_propertyName, p_value)
If index >= 0 Then
Return Me(index)
End If
Return Nothing
End Function
Run Code Online (Sandbox Code Playgroud)
它允许为T返回Nothing(null)
C#等价物不起作用:
public T FindItem(string p_propertyName, object p_value)
{
Int32 index = FindIndex(p_propertyName, p_value);
if (index >= 0) {
return this[index];
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
它不会使用此错误进行编译:
类型'T'必须是不可为空的值类型,以便在泛型类型或方法中将其用作参数'T'
'System.Nullable<T>'
我需要能够具有相同的功能,否则会破坏很多代码.我错过了什么?
c# ×4
.net ×2
.net-core ×1
asp.net-core ×1
generics ×1
nullable ×1
optional ×1
vb.net ×1
vb.net-to-c# ×1