仅getter的索引器参数可为null

  • 本文关键字:null 参数 getter 索引 c#
  • 更新时间 :
  • 英文 :


我有一个Field<T>类,它将Entity作为索引器参数:

class Entity { ... }
class Field<T>
{
T this[Entity? entity]
{
get
{
...
}
set
{
if (entity == null)
throw new ArgumentNullException(nameof(entity));
...
}
}
}

索引器getter应该允许空Entity值,而setter不应该,如下所示(不幸的是,它没有编译(:

class Field<T>
{
T this[Entity? entity] { get... }
T this[Entity entity] { set... }
}

有可能吗?

我不太确定您在示例代码中要做什么。您将Entity定义为一个类,这使它成为一个引用类型。您可以向编译器指示它是一个可为null的引用类型,但内部的类型是相同的。这与值类型不同,后者随着?而变得不同。(请参阅此处。(

所以EntityEntity?是相同的类型,但是int->CCD_ 9而CCD_;CCD_ 11。

这一点需要注意,因为索引器的定义方式。C#规范说

索引器的formal_parameter_list定义索引器的签名(§7.6(。具体来说,索引器的签名由其形式参数的数量和类型组成。形式参数的元素类型和名称不是索引器签名的一部分。

第14.9节索引器

您的代码

T this[Entity? entity] { get... }
T this[Entity entity] { set... }

由于两个签名相同,因此出现编译错误。

您可以通过各种方式来解决这一问题,并进行不同的权衡。您可以始终允许null和put运行时检查抛出异常。您可以删除setter和getter中的一个或两个,并将它们显式地实现为方法调用(因此您将丢失obj[index]语法(。您可以将Entity更改为值类型,并使用不同类型的签名实现两个不同的索引器;下面的例子。

namespace IndexerExample
{
public struct Entity
{
public int Id { get; set; }
}
public class Field<T>
{
private Dictionary<Entity, T> _values = new Dictionary<Entity, T>();
public T this[Entity? e]
{
get
{
if (!e.HasValue)
{
return default(T);
}
return _values[e.Value];
}
}
public T this[Entity e]
{
get
{
return _values[e];
}
set
{
if (_values.ContainsKey(e))
{
_values[e] = value;
}
else
{
_values.Add(e, value);
}
}
}
}
internal class Program
{
static void Main(string[] args)
{
var f = new Field<int>();
var e = new Entity() { Id = 3 };
f[e] = 9;
var x = f[null];
var y = f[e];
}
}
}

这对于索引器来说是不可能的。试试这个:

public T this[Entity? entity]
{
get
{
return this[entity];
}
set
{
// check for not null
this[entity] = value;
}
}

希望能有所帮助!

从这里开始:

[DisallowNull]
public string? ReviewComment
{
get => _comment;
set => _comment = value ?? throw new ArgumentNullException(nameof(value), "Cannot set to null");
}
string? _comment;

在可为null的上下文中,ReviewComment get访问器可以返回null的默认值。编译器警告说,在访问之前必须对其进行检查。此外,它警告调用方,即使它可能为null,调用方也不应该显式地将其设置为null。DisableNull属性还指定了一个前提条件,它不会影响get访问器。当您观察到以下关于的特征时,可以使用DisableNull属性

在核心场景中,变量可能为null,通常是在第一次实例化时。该变量不应显式设置为null。

毫无疑问,您可以使索引器适应这一点。

最新更新