c# = проблема оператора

В C# у меня есть простой 3D векторный класс.

static void Main(string[] args)
{
    Vector3D a, b;
    a = new Vector3D(0, 5, 10);
    b = new Vector3D(0, 0, 0);

    b = a;
    a.x = 10;

    Console.WriteLine("vector a=" + a.ToString());
    Console.WriteLine("vector b=" + b.ToString());
    Console.ReadKey();
}

вывод,

векторизуйте = 10, 5, 10

вектор b = 10, 5, 10

Я присваиваюсь, прежде чем я изменю a.x на 10. Таким образом, я ожидал

векторизуйте = 10, 5, 10

вектор b = 0, 5, 10

Из того, что я понимаю =, оператор присваивает ссылку для возражения как указатель? И в C# я не могу перегрузиться = оператор.

Я должен вручную присвоить каждое свойство?

6
задан Kayhano 27 July 2010 в 20:39
поделиться

6 ответов

Да, поскольку Vecor3D относится к классу , это совершенно правильно.

Классы являются ссылочными типами, и ваш оператор b = a; копирует не экземпляр Vector3D, а ссылку на экземпляр.

Если вы хотите «клонировать» экземпляры, вы можете добавить интерфейс IClonable, но от этого более или менее отказались.

Лучшее решение для типа могло бы состоять в том, чтобы сделать его структурой. Структуры - это типы значений, и значение b = a; изменится (в сторону желаемого).

3D-точка соответствует всем критериям структуры (маленькая, без идентичности). Предпочтительный способ - сделать его неизменным.

10
ответ дан 8 December 2019 в 12:57
поделиться

Да, « = оператор назначает ссылку на объект как указатель », как вы выразились. Таким образом, и a , и b ссылаются на один и тот же одиночный объект в памяти. (Объект, на который ранее ссылался b , больше не упоминается и будет собираться мусором.)

Есть несколько способов решить эту проблему:

  1. Сделайте Vector3D a struct вместо класса.Структуры являются типами значений вместо ссылочных типов, поэтому b = a копирует содержимое a в переменную b .

  2. Реализуйте метод Clone в своем классе Vector3D (ранее это означало реализацию ICloneable , но это больше не рекомендуется ). В качестве альтернативы вы можете создать конструктор Vector3D , который принимает другой вектор в качестве параметра и создает копию.

  3. Вручную скопируйте три значения самостоятельно ( b = new Vector3D (a.x, a.y, a.z) ), если вы не можете изменить реализацию Vector3D .

3
ответ дан 8 December 2019 в 12:57
поделиться

Возможно, вы захотите изменить свой класс Vector3D на struct. Это позволит вам работать с типом значений вместо ссылочного типа.

Другой вариант - реализовать ICloneable или использовать какой-нибудь другой метод для создания глубокой копии вашего объекта.

2
ответ дан 8 December 2019 в 12:57
поделиться

Да, ссылочные типы присваиваются по ссылке.

Если вы хотите иметь отдельный экземпляр, вам нужно CLONE ваш экземпляр.

Создайте метод Vector3D.Clone(), который будет выглядеть примерно так:

public Vector3D Clone()
{
    return new Vector3D(this.x, this.y, this.x);
}

Тогда ваш Main должен выглядеть так:

static void Main(string[] args)
{
    Vector3D a, b;
    a = new Vector3D(0, 5, 10);
    b = new Vector3D(0, 0, 0);

    b = a.Clone();
    a.x = 10;

    Console.WriteLine("vector a=" + a.ToString());
    Console.WriteLine("vector b=" + b.ToString());
    Console.ReadKey();
}

Но, как говорили другие, что-то такое маленькое, как Vector3D, лучше использовать как неизменяемую структуру

.
2
ответ дан 8 December 2019 в 12:57
поделиться

Вы можете сделать его структурой, как говорит Хенк. И вы можете добавить конструктор

struct Vector3D
{
    public int x;
    public int y;
    public int z;

    public Vector3D(int x, int y, int z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
    public override string ToString()
    {
        return string.Format("{0}, {1}, {2}", x, y, z);
    }
}   

Вы также можете сделать это без добавления конструктора.

b = new Vector3D() {x=0, y=0, z=0};
1
ответ дан 8 December 2019 в 12:57
поделиться

Нет необходимости использовать struct , я предлагаю вам разработать свой Vector3D как неизменяемый класс. Вот несколько хороших примеров. Конечно, a.x = 10 невозможно для неизменяемого класса.

0
ответ дан 8 December 2019 в 12:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: