gpt4 book ai didi

c# 8 nullable + 字典<>

转载 作者:行者123 更新时间:2023-12-04 04:06:10 24 4
gpt4 key购买 nike

我的代码看起来像这样:

#nullable enable
class MyClass<KEY, ITEM>
{
readonly Dictionary<KEY, ITEM> Map = new Dictionary<KEY, ITEM>();
public void Process(KEY key, ITEM item)
{
if (key != null)
{
Map[key] = item;
}
}
}
#nullable disable

编译器对此并不满意,它给了我警告

type 'KEY' cannot be used as type parameter 'TKey' in the generic type or method 'Dictionary<TKey, TValue>

我当然可以理解。问题是,将“key”参数的 null 发送到 Process() 是完全有效的,因此我无法将“where KEY: notnull”约束添加到类中。 (并且 MyClass 需要接受 KEY 类型参数的类和结构)

我唯一能想到的是:

#nullable enable
class MyClass<KEY, ITEM>
{
#nullable disable
readonly Dictionary<KEY, ITEM> Map = new Dictionary<KEY, ITEM>();
#nullable enable
public void Process(KEY key, ITEM item)
{
if (key != null)
{
Map[key] = item;
}
}
}
#nullable disable

这让编译器很满意,但是我没有所有那些不错的 C# 8 空值检查。例如,它允许我编写以下代码:

Map[default] = item;

而且编译器连眼睛都不眨一下。

我如何告诉编译器 Dictionary<> 的“KEY”类型参数应该禁止空值,但仍然允许外部类中的 KEY 值为空值?

编辑

我想使用新的 C# 8 可空性功能,以便在编译时捕获尽可能多的空指针(而不是等待运行时异常)。

进一步编辑

我现在的方向是在 Dictionary 周围放置一个薄层以强制执行 null 限制并使用它代替 Dictionary<>

#nullable enable
public class CheckDictionary<KEYTYPE, VALUETYPE>
{
#nullable disable
readonly Dictionary<KEYTYPE, VALUETYPE> Dictionary = new Dictionary<KEYTYPE, VALUETYPE>();
#nullable enable

public VALUETYPE this[[DisallowNull] KEYTYPE key]
{
get { return Dictionary[key]; }
set { Dictionary[key] = value; }
}

public bool Remove([DisallowNull] KEYTYPE key)
{ return Dictionary.Remove(key); }

public bool TryGetValue([DisallowNull] KEYTYPE key, out VALUETYPE value)
{ return Dictionary.TryGetValue(key, out value); }

public List<VALUETYPE> Values => Dictionary.Values.ToList();
}

最佳答案

我认为在您的情况下可以使用下一种方法:

  • 将类型参数 TKey 约束为 notnull。因此,编译器将对 TKey 执行空检查。
  • 添加 AllowNullAttribute到方法 Process 的参数 TKey key。因此,将 null key 传递给方法 Process 的代码不会产生警告。

下面是带注释的代码:

class MyClass<TKey, TItem> where TKey : notnull
{
// With "notnull" constraint type parameter "TKey" matches type constraint
// of the class Dictionary<TKey, TValue>, therefore compiler does not
// generate the next warning:
// The type 'TKey' cannot be used as type parameter 'TKey' in the
// generic type or method 'Dictionary<TKey, TValue>'. Nullability
// of type argument 'TKey' doesn't match 'notnull' constraint.
readonly Dictionary<TKey, TItem> Map = new Dictionary<TKey, TItem>();

public void Process([System.Diagnostics.CodeAnalysis.AllowNull] TKey key, TItem item)
{
// "TKey key" is marked with [AllowNull] attribute. Therefore if you delete
// null check "key != null" compiler will produce the next warning on the line
// "Map[key] = item":
// Possible null reference argument for parameter 'key' in
// 'TItem Dictionary<TKey, TItem>.this[TKey key]'.
if (key != null)
Map[key] = item;

// Because "TKey" is constrained to be "notnull", this line of code
// produces the next warning:
// Possible null reference argument for parameter 'key' in
// 'TItem Dictionary<TKey, TItem>.this[TKey key]'.
Map[default] = item;
}
}

static class DemoClass
{
public static void Demo()
{
MyClass<string, int> mc1 = new MyClass<string, int>();
// This line does not produce a warning, because "TKey key" is marked
// with [AllowNull] attribute.
mc1.Process(null, 0);
// This line does not produce a warning too.
mc1.Process(GetNullableKey(), 0);

// Usage of "MyClass" with value type "TKey" is also allowed.
// Compiler does not produce warnings.
MyClass<int, int> mc2 = new MyClass<int, int>();
mc2.Process(0, 1);
}

public static string? GetNullableKey() => null;
}

因此使用这种方法我们:

  • MyClass 中的 TKey 实现空检查;
  • 允许将 null key 传递给 Process 方法而不会收到警告。

关于c# 8 nullable + 字典<>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62458140/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com