Имитатор C# сверхизбавление оператора присваивания (=)

Ваш Try2 очень близок к решению. Попробуйте переместить включающий внешний экстерьер «С». Обычно я просто отмечаю каждую функцию отдельно:

extern "C" void foo() 
{
...
}

Преимущество этого состоит в том, что вы просто экспортируете один символ как символ C, а не пытаетесь преобразовать все.

6
задан 13 March 2009 в 22:34
поделиться

7 ответов

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

Одна опция состоит в том, чтобы перегрузить конструктора:

public Wrapper(Wrapper<T> w)
{
    _value = w._value;
}

Который привел бы к этому синтаксису:

Wrapper<int> foo = 42;
Wrapper<int> bar = new Wrapper<int>(foo);

Хотя более подробный, чем, что Вы имеете, это читает лучше.

Или Вы могли добавить a Clone метод (не ICloneable интерфейс), так, чтобы Вы могли записать:

Wrapper<int> bar = foo.Clone();

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

5
ответ дан 10 December 2019 в 00:45
поделиться

Вы могли сделать Обертку <T> a struct. Однако я не уверен, удовлетворило ли это Вашему проектированию приложений или нет.

3
ответ дан 10 December 2019 в 00:45
поделиться

При рассмотрении Nullable <T>..., который делает очень похожую вещь к тому, что Вы делаете здесь, он выставляет внутреннее значение с помощью.Value свойства.

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

Я не уверен, что следую за этим, что точно Вы храните в словаре? Поскольку при хранении ссылок CLR обновит их по мере необходимости.

1
ответ дан 10 December 2019 в 00:45
поделиться

Это - то, для чего свойства. Они позволяют Вам определять то, что означает присвоение. Вы не можете определить его для класса или самой структуры, потому что они уже определяются языком, чтобы сделать необходимые вещи. Просто добавьте a Value свойство к классу.

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

0
ответ дан 10 December 2019 в 00:45
поделиться

Неявно не бросайте свою обертку оба пути.

public class DBValue<T>
{
    public static implicit operator DBValue <T>(T value)
    {
         return new DBValue<T>(value);
    }

    public static explicit operator T(DBValue <T> dbValue)
    {
         return dbValue.Value;
    }

    private readonly T _value;
    public T Value { get { this._value; } }

    public DBValue(T value)
    {
         this._value = value;
    }
}

Кастинг от DBValue<T> кому: T преобразование с потерями (как минимум, Вы теряете то, что это - значение от базы данных), и лучшей практикой должно быть явным. Если Вы ничего не теряете путем кастинга от DBValue<T> кому: T, Вы могли бы также просто использовать свойства тот возврат T.

В основном Вы уже видели, почему Вы не должны пытаться сделать это: если DBValue можно заменить T и наоборот, как делает компилятор (или разработчик) знают который выбрать?

Требование, чтобы нисходящие разработчики записали:

string value = MyProperty.Value

или

string value = (string)MyProperty

вместо

string value = MyProperty

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

Править:

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

1
ответ дан 10 December 2019 в 00:45
поделиться

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

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

Я могу отправить весь класс, если это было бы полезно, но это несколько длинно (130 строк), Или я мог бросить на отдельном сервере, если это будет лучше? (хотя это повреждает целостность этого вопроса, поскольку я могу удалить его в конечном счете из того сервера),

Также объяснение класса является действительно трудным, не пишущий полное эссе :-/

Так или иначе я попытаюсь проиллюстрировать проблему, которую я имею.

Примите 2 класса таблицы: CustomerTable и UserTable:

public class CustomerTable
{
  Wrapper<string> Name;
}

public class UserTable
{
  Wrapper<string> Name;
}

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

CustomerTable customer = new CustomerTable();
UserTable user = new UserTable();
user.Name = customer.Name; // This breaks my internal dictionary

То, что должен разработчик, сделало для него для работы, был:

user.Name = (string)customer.Name;

Проблема однако, кто в их правильном уме думал бы об этом, когда написание кода?

Даже если бы я использовал свойство Value, то разработчик должен был бы все еще не забыть писать

user.Name = customer.Name.Value; // or user.Name.Value = ....

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

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

Уф большая запись и много кода - сообщают мне, переусердствовал ли я запись.

0
ответ дан 10 December 2019 в 00:45
поделиться

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

Причина для неявного броска от DbValue до T, только к функциям, который ожидает T.

например,

literalSomething.Text = Server.HtmlEncode(SomeTable.SomeStringColumn);

вместо

literalSomething.Text = Server.HtmlEncode((string)SomeTable.SomeStringColumn);

Это требует, чтобы бросок был неявен.

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

Я думаю, что вернусь к представлению значения через свойство, оно просто требует, чтобы разработчик ввел больше и отчасти делает код ужасным, я думаю.

Просто вообразите DbValue:

if (someValue.Value.HasValue) // someValue is DbValue<int?>

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

Я предполагаю, что этот вопрос заканчивается как вопрос "о лучшей практике" действительно.

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

Спасибо за Ваши исходные данные :-)

0
ответ дан 10 December 2019 в 00:45
поделиться
Другие вопросы по тегам:

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