无法解释的错误:记录成员必须是类型为“T[]”的可读实例属性或字段,以匹配位置参数

Unexplainable error: Record member must be a readable instance property or field of type 'T[]' to match positional parameter

提问人:Zenith 提问时间:11/13/2023 更新时间:11/13/2023 访问量:103

问:

我正在尝试将几个数组包装在一个包装器中,如下所示:Dto

public sealed record SomeWrapper<T>(T[]? L1, T[]? L2, T[]? L3) 
    : SomeWrapper(L1, L2, L3) where T : Dto;

public record SomeWrapper(
    Dto[]? L1,
    Dto[]? L2,
    Dto[]? L3
);

因为我希望能够初始化一个数组,其中 T 可以不同,IE:SomeWrapper

List<SomeWrapper> someWrappers = new List<SomeWrapper>()

someWrappers.Add(new SomeWrapper<SomeDto>());
someWrappers.Add(new SomeWrapper<SomeOtherDto>());
return someWrappers;

但是,我收到以下错误:Record member 'L1' must be a readable instance property or field of type 'T[]' to match positional parameter 'L1'

我相信这段代码应该可以工作,所以我不确定这里出了什么问题。如下所示:Dto

public interface Dto<T> : Dto where T : Entity.Entity;

public interface Dto
{
    string Id { get; init; }
};

Entity目前只是一个空接口。

我无法解释这个错误,也不知道该如何问这个问题(接受建议)

C# .NET 泛型继承

评论

1赞 Somar Zein 11/13/2023
我认为试图达到的内容在记录中是不允许的,请参阅此 git 讨论
0赞 Zenith 11/13/2023
有趣。老实说,我不能说我完全理解讨论,但理解后果。有效的解决方案是将 Dto 更改为类吗?尝试这样做会导致铸造出现类似问题

答:

1赞 shingo 11/13/2023 #1

让我简化你的问题,当你有:

public record SomeWrapper(Dto[]? L1);

编译器会自动生成同名的公共属性:

public record SomeWrapper
{
    public Dto[]? L1 { get; init; }
    // ...other members
}

现在,在派生的记录中,声明一个同名的属性:

public sealed record SomeWrapper<T>(T[]? L1) : SomeWrapper(L1) where T : class, Dto

编译器将假定这是基类定义的属性。但是,由于您声明了不同的类型,因此它不再起作用。此错误消息在某种程度上具有误导性,因为它建议您修改基类的属性类型。L1L1

无论如何,你需要解决这个冲突,我认为你不想遇到意想不到的错误。您需要手动声明一个新属性:

public sealed record SomeWrapper<T>(T[]? L1) : SomeWrapper(L1) where T : class, Dto
{
    public new T[]? L1 => (T[]?)base.L1;
}

评论

0赞 Zenith 11/13/2023
感谢您抽出宝贵时间接受采访。当我应用您建议的解决方案时,我收到一个新错误:任何建议?Cannot convert type Dto[]? to T[]?
0赞 Zenith 11/13/2023
我进行了一些编辑以更准确地反映问题,然后发生了错误: dotnetfiddle.net/t0tK28
0赞 shingo 11/13/2023
哦,我删除了约束以简化问题,但您的原始代码应该保留它。T:class
0赞 Zenith 11/13/2023
我不太明白你的意思。你的意思是你的解决方案在我的情况下不起作用吗?
1赞 shingo 11/13/2023
是的,它有效,我更新了我的答案,--->.where T : Dtowhere T : class, Dto