Подтвердить что ты не робот

Проблема со структурой и свойством в С#

в файле я определил публичную структуру

public struct mystruct
{
    public Double struct1;
    public Decimal struct2;
}

В другом я попытался сделать это:

class Test
{
    mystruct my_va;

    public mystruct my_va
    {
        get { return my_va; }
        set { my_va = value; }
    }

    public Test()
    {
        my_va.struct1 = 10;
    }
}

Intellisense распознает My_va.struct1, но компилятор говорит

Ошибка 1 Невозможно изменить возвращаемое значение 'TEST.mystruct', потому что это не Переменная

Как исправить синтаксис?

4b9b3361

Ответ 1

Настоятельно рекомендуется избегать изменчивых структур. Они демонстрируют все виды удивительного поведения.

Решение. Сделайте свою структуру неизменной.

public struct MyStruct
{
    public readonly double Value1;
    public readonly decimal Value2;

    public MyStruct(double value1, decimal value2)
    {
        this.Value1 = value1;
        this.Value2 = value2;
    }
}

Использование:

class Test
{
    private MyStruct myStruct;

    public Test()
    {
        myStruct = new MyStruct(10, 42);
    }

    public MyStruct MyStruct
    {
        get { return myStruct; }
        set { myStruct = value; }
    }
}

Ответ 2

Да, это абсолютно правильно. Вы видите, когда вы получаете My_va, вы получаете значение - копию текущего значения My_va. Изменение этого значения не принесет никакой пользы, потому что вы сразу же отбросите копию. Компилятор останавливает вас от написания кода, который не делает то, что выглядит так.

В общем, избегайте изменчивых структур. Они злы. В этом случае вы могли бы (например) изменить mystruct на неизменяемость, но с помощью метода, подобного этому:

public mystruct WithStruct1(double newValue)
{
    return new mystruct(newValue, struct2);
}

затем измените код конструктора на:

My_va = My_va.WithStruct1(10);

... хотя в этом случае это гораздо более вероятно (учитывая, что вы находитесь в конструкторе), который вы должны писать:

My_va = new mystruct(10, 0);

Не обязательно, чтобы структуры были неизменными, они должны быть довольно редкими в большинстве кодовых баз, ИМО. Кроме Noda Time, я почти никогда не писал свои собственные типы значений.

Наконец, ознакомьтесь с .NET соглашениями об именах и попытайтесь выполнить их, даже для образца кода:)

Ответ 3

Простейшее исправление: измените структуру на класс.

Ответ 4

Я работаю со списком структур и решил это по-другому.

struct Pixel
{ Public int X;
  Public int C;
}
List<Pixel> PixelList = new List<Pixel>
TempPixel = new Pixel();

Теперь, когда я хочу установить значение я code следующим образом:

TempPixel = PixelList[i];
TempPixel.X= 23;  // set some value
PixelList[i] = TempPixel

Код выглядит немного странным, возможно, но он решает проблему. Он решает проблему того, что для структуры не может быть напрямую назначено одно значение, но может быть копией аналогичного типа. решающая ошибка CS1612:

https://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k%28CS1612%29;k%28TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV2.0%22%29;k%28DevLang-CSHARP%29&rd=true

Ответ 5

К сожалению, эта ошибка может быть сгенерирована некорректно при назначении свойства (т.е. при вызове средства настройки свойств). У неизменяемой структуры все еще может быть допустимый набор свойств, если набор свойств не назначается ни одному из полей в структуре. Например,

public struct Relay
{
    public Relay(Func<string> getText, Action<string> setText)
    {
        this.GetText = getText;
        this.SetText = setText;
    }
    private readonly Func<string> GetText;
    private readonly Action<string> SetText;

    public string Text {
        get { return this.GetText(); }
        set { this.SetText(value); }
    }
}

class Example
{
    private Relay Relay {
        get { return new Relay(() => this.text, t => { this.text = t; }); }
    }

    private string text;


    public Method()
    {
        var r = new Relay();
        r.Text = "hello"; // not a compile error (although there is a null reference)

        // Inappropriately generates a compiler error
        this.Relay.Text = "hello";

        r = this.Relay;
        r.Text = "hello"; // OK
    }
}