【问题标题】:How can I modify a value in a struct?如何修改结构中的值?
【发布时间】:2012-12-09 03:44:34
【问题描述】:

我的结构类:

public struct PinAndRadius
{
    public string pinID { get; set; }
    public string radiusID { get; set; }

    public string getPinID()
    {
        return pinID;
    }

    public string getRadiusID()
    {
        return radiusID;
    }
}

有问题的方法:

void mapArea_VE_PinDragged(double latitude, double longitude, object id)
{
    foreach (var pin in pinRadiusCollection)
    {
        string ID = id.ToString();
        //string newID = ID.Substring(0, 18);
        if (!pin.Key.pinID.Equals(ID))
        {
            continue;
        }
        else if (pin.Key.pinID.Equals(ID))
        {
            var newLoc = createNewSearchLocation(latitude, longitude);
            mapArea.VE_DeleteRadius(pin.Key.radiusID);
            drawPoly(newLoc, pin.Value.xar_Radius);
            pin.Key.radiusID = pollyID;
            break;
        }
    }
}

问题是当我尝试将 pin.key.radiusID 设置为 pollyID 时,我收到一条错误消息

不能修改'System.Collections.Generic.KeyValuePair.Key'的返回值,因为它不是变量...

有什么想法吗?

【问题讨论】:

    标签: collections struct variable-assignment


    【解决方案1】:

    .net 中的结构是值类型的。这意味着您无法使用pin.Key 获得对PinAndRadius 的引用。您将获得PinAndRadius 类型的pin.Key 的副本。然后您无法访问此副本,编译器会告诉您这一点。在 C++ 术语中,它不是左值。

    如果您创建 struct,请始终尝试使其不可变。可变结构是邪恶的。

    解决此问题的最简单方法是将PinAndRadius 设为class

    【讨论】:

      【解决方案2】:

      从外观上看,您的pinRadiusCollection 是由PinAndRadius 键入的通用字典;您遇到的错误是让您知道您无法修改该对象,因为它被用作字典中的键。

      如果您的 pin 应该是可变的,您可能应该重新考虑如何存储它们。

      【讨论】:

        【解决方案3】:

        .net 中的集合未设置为允许方便地修改其中包含的结构类型项目。尽管如此,可变结构仍然提供比任何其他类型的数据类型更清晰的语义。要编辑集合中的结构,只需将其复制到变量中,编辑该变量并将其存储回来:

        var temp = myList[someIndex];
        temp.SomeVield = whatEver;
        myList[someIndex] = temp;
        

        请注意,通常将可变结构的内容作为字段公开比作为属性公开要好。有些人可能会说可变结构是邪恶的,因为它们的语义与类不同,但这就像说螺丝刀是邪恶的,因为它们制造了糟糕的锤子。暴露字段结构不像类类型那样工作,但是所有字段都暴露的结构都具有彼此相同的语义。这些语义与类不同,但对于它们有用的情况,它们是不平等的。

        顺便说一句,“可变结构”得到的大部分不良代表是因为如果应用于只读结构,除了暴露字段之外的可变结构成员通常会生成虚假代码。如果您避免使用修改this 字段的结构成员[静态结构方法修改作为ref 参数接收的结构字段是完全安全的],则这些危险不适用。

        【讨论】:

          【解决方案4】:

          我只是将结构定义更改为一个类。

          【讨论】:

          • 你了解结构和类的区别吗?更改为类将使代码编译,但语义与使用结构时的语义不同。有些情况需要类似结构的语义(在这种情况下应该使用我建议的方法),而其他情况需要类语义。如果PinAndRadius 类型的变量存储在集合中,然后变量的RadiusId 随之更改,您是否希望集合中的RadiusId 也更改?如果你这样做,一个可变类将是合适的。如果没有...
          • ...那么使用可变类是错误的(因为更改通过对实例的一个引用访问的属性会更改对该实例的所有引用看到的属性)。除了相对较少的例外,每个可变对象实例在任何给定时间都需要只有一个所有者,并且任何持有对可变对象的引用的代码都需要知道它是否拥有所讨论的对象。没有正式的机制来跟踪谁拥有什么,但是在不知道谁拥有它们的情况下传递混杂的对象引用是导致错误的秘诀。
          • 在这种情况下,集合应该会经常更改,因为我将从中删除因此我使用可变类的原因,我对 C# 很陌生,所以我非常感谢您提供的解释,真的有帮助
          • 如果你使用一个可变类,然后说myCollection.Add(myThing),然后说myThing.someProperty = 23;,结果将是集合包含对someProperty值为23的事物的引用。如果是这样你所追求的,那么你的类型几乎肯定应该是一个可变类。如果这不是您所追求的,那么使用可变类很危险。
          猜你喜欢
          • 2020-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多