Могу ли я указать значение конструктора с помощью оператора =? - PullRequest
0 голосов
/ 04 мая 2018

При создании строки в C # вы должны сделать string foo = "bar"; string, являющейся классом, и значение "bar" будет передано классу с помощью оператора =. Как это было сделано? Не могли бы вы сделать это в своем классе?

Я знаю, что это выполнимо в C ++ как таковом.

class someClass {
public:
    someClass(int someInt) {
        // Do Stuff
    }

};

int main() {
    someClass classInst = 123;
}

Но что будет эквивалентно C #?

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Вы можете определить неявные преобразования между двумя типами: int и SomeClass, как показано ниже:

// User-defined conversion from SomeClass to int
public static implicit operator int(SomeClass someClass)
{
    return someClass.SomeInt;
}
//  User-defined conversion from int to SomeClass
public static implicit operator SomeClass(int someInt)
{
    return new SomeClass(someInt);
}

Эти методы должны быть определены в SomeClass объявлении.

Для получения дополнительной информации о неявном преобразовании проверьте эту ссылку .

0 голосов
/ 04 мая 2018

Этот вопрос состоит из двух частей:

  • Как работают строковые литералы
  • Как сделать то же самое для своего класса

Строковые литералы

Выражение "bar" уже является значением типа string. Оператор присваивания здесь просто копирует ссылку, как и для всего остального. Строковые литералы приводят к тому, что строковые объекты создаются, где это возможно (но используются повторно, поэтому, если у вас есть этот код в цикле, есть только один объект string). Здесь есть некоторая тонкость для интерполированных строковых литералов вокруг FormattableString, но я проигнорирую это для целей этого вопроса.


Создание собственного буквально-подобного синтаксиса

Вы не можете сделать так, чтобы оператор присваивания неявно вызывал конструктор напрямую, нет. Вы могли бы добавить неявное преобразование из int в SomeClass, но я бы вообще не одобрял это.

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

using System;

class SomeClass
{
    public int Value { get; }

    public SomeClass(int value) => Value = value;

    public static implicit operator SomeClass(int value) =>
        new SomeClass(value);
}

public class Program
{
    static void Main()
    {
        SomeClass x = 123;
        Console.WriteLine(x.Value);
    }
}

Обратите внимание, что если в C # 8 появится функция target-typed new, вы сможете написать:

SomeClass x = new(123);

... чтобы вы, по крайней мере, сохранили дублирование там, даже для полей.

...