相关疑难解决方法(0)

具有泛型返回类型的可空引用类型

我正在使用新的C#8可空引用类型功能,并在重构我的代码时,我遇到了这个(简化)方法:

public T Get<T>(string key)
{
    var wrapper = cacheService.Get(key);
    return wrapper.HasValue ? Deserialize<T>(wrapper) : default;
}
Run Code Online (Sandbox Code Playgroud)

现在,这给出了一个Possible null reference return逻辑上的警告,因为default(T)将为所有引用类型赋予null.起初我以为我会把它改成以下内容:

public T? Get<T>(string key)

但这不可能做到.它说我要么必须添加通用约束where T : classwhere T : struct.但是,这是不是一种选择,因为这既可以是(我可以存储intint?或实例FooBar在缓存或其他).我还读到了一个假定的新泛型约束,where class?但似乎没有用.

我能想到的唯一简单的解决方案是使用null forgiving运算符更改return语句:

return wrapper.HasValue ? Deserialize<T>(wrapper) : default!;
Run Code Online (Sandbox Code Playgroud)

但这感觉不对,因为它肯定是空的,所以我基本上对这里的编译器撒谎:-)

我怎样才能解决这个问题?我错过了一些完全明显的东西吗?

c# generics c#-8.0 nullable-reference-types

28
推荐指数
4
解决办法
977
查看次数

当空引用似乎不可能时,为什么我们会收到可能取消引用空引用警告?

在HNQ 上阅读了这个问题后,我继续阅读C# 8 中的可空引用类型,并做了一些实验。

我非常清楚,当有人说“我发现了一个编译器错误!”时,10 次中有 9 次,甚至更频繁。这其实是有意为之,也是自己的误会。而且因为我今天才开始研究这个功能,显然我对它不是很了解。有了这个,让我们看看这段代码:

#nullable enable
class Program
{
    static void Main()
    {
        var s = "";
        var b = s == null; // If you comment this line out, the warning on the line below disappears
        var i = s.Length; // warning CS8602: Dereference of a possibly null reference
    }
}
Run Code Online (Sandbox Code Playgroud)

在阅读我上面链接的文档后,我希望该s == null行给我一个警告——毕竟s显然是不可为空的,所以将它与它进行比较null是没有意义的。

相反,我在下一行收到警告,警告说这s可能是一个空引用,即使对于人类来说,很明显它不是。

此外,如果我们不与 进行比较,则不会显示警告。 …

c# roslyn c#-8.0 nullable-reference-types

19
推荐指数
2
解决办法
7954
查看次数

非可空类型的通用约束

我有以下课程:

public class KeyDTO<T>
{
     public T Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止一切顺利,但我希望类型参数T是一个非可空类型.我在某处读过这可能是可行的:

public class KeyDTO<T> where T : IComparable, IComparable<T>
{
     public T Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我public T Id改为public T? Id,我会收到编译错误,告诉我T必须是不可为空的.

如何指定泛型类型参数必须是非可空的?

编辑

我想完成这个,因为我想Id[Required]属性注释我的属性,如下所示:

public class KeyDTO<T> {
    [Required]
    public T Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

什么[Required]是验证模型,因此T不能为空.

但是,如果我有KeyDTO<int>,Id将被初始化为0,绕过我的[Required]属性

.net c# generics types interface

12
推荐指数
2
解决办法
7251
查看次数

C# 9 可空类型问题

考虑以下(VS 16.8.0 Preview 2.1 C# 9.0 preview)代码:

#nullable enable

using System.Collections.Generic;

class Archive<T> where T : notnull 
{
  readonly Dictionary<string, T> Dict = new();

  public T? GetAt(string key) 
  { 
    return Dict.TryGetValue(key, out var value) ? value : default;
  }
}

class Manager 
{
  public int Age { get; set; }
}

class Main34 
{
  long F3() 
  {
    Archive<long> a = new();
    var johnAge = a.GetAt("john");
    if (johnAge is null) return -1; // Error CS0037  Cannot convert null to 'long' because …
Run Code Online (Sandbox Code Playgroud)

c# c#-8.0 c#-9.0

6
推荐指数
1
解决办法
958
查看次数