C# 为结构错误的属性赋值

C# assigning value to property of struct error

提问人:Nick 提问时间:12/12/2019 最后编辑:Bill Tür stands with UkraineNick 更新时间:12/12/2019 访问量:200

问:

我有以下代码(简化),一个结构和一个类。

public struct pBook
{
    private int testID;

    public string request;
    public string response;
    public Int32 status;
    public int test_id
    {
        get
        {
            return testID;
        }
        set
        {
            testID = value;
        }
    }
};

public class TestClass
{
    public static void Main(string[] args)
    {
        pBook Book1;
        pBook Book2;

        Book1.request = "a";
        Book2.response = "b";
        Book2.status = 201;
        Book2.test_id = 0;  //this doesn't work, why?
    }
}

在声明

Book2.test_id = 0;

我收到错误

使用未分配的局部变量“Book2”

有什么想法如何纠正吗?

C# 结构

评论

0赞 René Vogt 12/12/2019
区别在于它是一个属性,因此这实际上是一个方法调用,而其他赋值仅访问字段。但对我来说,这感觉不一致,其他作业也应该出现错误,或者根本不会出现。test_id
0赞 panoskarajohn 12/12/2019
您将其作为专用test_id。专用访问是允许最低的访问级别。私有成员只能在类的主体或结构体中访问 -> learn.microsoft.com/en-us/dotnet/csharp/language-reference/...
1赞 Peter B 12/12/2019
我认为这两个“重复”问题都选择得不好,因为它们没有处理场景。此副本确实处理结构:结构初始化和新运算符struct
1赞 12/12/2019
@PeterB 理解,回想起来,我同意。对于给您带来的不便,我深表歉意。

答:

7赞 Marc Gravell 12/12/2019 #1

在“定赋值”中,a 要求在调用方法之前赋值所有字段,属性(甚至属性设置者)都是方法。懒惰的修复很简单:struct

var Book2 = default(pBook);
// the rest unchanged

它通过显式地将所有内容设置为零来愚弄确定的赋值。然而!IMO,这里真正的解决方法是“没有可变的结构”。可变的结构会伤害你。我建议:

var Book2 = new pBook("a", "b", 201, 0);

with (注意:这使用最新的 C# 语法;对于较旧的 C# 编译器,您可能需要进行一些调整):

public readonly struct Book
{
    public Book(string request, string response, int status, int testId)
    {
        Request = request;
        Response = response;
        Status = status;
        TestId = testId;
    }
    public string Request { get; }
    public string Response { get; }
    public int Status { get; }
    public int TestId { get; }
};

评论

0赞 Nick 12/12/2019
绝对精彩,谢谢(谢谢你的建议)。因此,我保留了能够阅读的权限,并且作为“集合”,我使用公共 Book(string...等等,对吧?
0赞 Eric Lippert 12/13/2019
@Nick:没错。使用不可变结构,您不会更改单个字段。将整个结构替换为不同的结构。就像当你把 3 加到 2 时,你不会把 2 或 3 变成 5。2 和 3 保持 2 和 3;你产生了一个新的价值。结构是值类型,因此应将它们视为,而不是可变状态。
0赞 Brian 12/13/2019
如果您确实发现自己想要更改不可变结构上的单个字段,一个常见的解决方法是添加一个 Fluent 接口来执行此操作。例如,或者,广义函数可以工作(例如,)。这些类型的函数(可选地作为扩展方法实现)只是对构造函数的简单调用。book = book.WithStatus(5);book = book.With(Status:5);