Препроцессор C#

(добавление ответа, потому что примеров с универсальными символами Generics недостаточно)

       // Source 
       List<Integer> intList = Arrays.asList(1,2,3);
       List<Double> doubleList = Arrays.asList(2.78,3.14);
       List<Number> numList = Arrays.asList(1,2,2.78,3.14,5);

       // Destination
       List<Integer> intList2 = new ArrayList<>();
       List<Double> doublesList2 = new ArrayList<>();
       List<Number> numList2 = new ArrayList<>();

        // Works
        copyElements1(intList,intList2);         // from int to int
        copyElements1(doubleList,doublesList2);  // from double to double


     static <T> void copyElements1(Collection<T> src, Collection<T> dest) {
        for(T n : src){
            dest.add(n);
         }
      }


     // Let's try to copy intList to its supertype
     copyElements1(intList,numList2); // error, method signature just says "T"
                                      // and here the compiler is given 
                                      // two types: Integer and Number, 
                                      // so which one shall it be?

     // PECS to the rescue!
     copyElements2(intList,numList2);  // possible



    // copy Integer (? extends T) to its supertype (Number is super of Integer)
    private static <T> void copyElements2(Collection<? extends T> src, 
                                          Collection<? super T> dest) {
        for(T n : src){
            dest.add(n);
        }
    }
20
задан Brian Tompsett - 汤莱恩 8 July 2016 в 13:17
поделиться

9 ответов

Рассмотрите взгляд на аспектно-ориентированное решение как PostSharp, который вводит код после факта на основе пользовательских атрибутов. Это - противоположность предварительного компилятора, но может дать Вам вид функциональности, которую Вы ищете (уведомления PropertyChanged и т.д.).

11
ответ дан 30 November 2019 в 00:44
поделиться

я должен создать препроцессор C#? Действительно ли там каждый доступен, который делает простые вещи, которые я хочу сделать?

можно всегда использовать препроцессор C - C# достаточно близок, мудр синтаксисом. M4 является также опцией.

6
ответ дан 30 November 2019 в 00:44
поделиться

Я знаю, что много людей думает, что короткий код равняется изящному коду, но это не верно.

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

С Вашим примером, Куда Вы помещаете предел? Очевидно это удовлетворяет шаблон "наблюдатель" и нет сомнения, что который будет полезен, но существует много вещей, которые были бы полезны, которые на самом деле сделаны, потому что код обеспечивает гибкость , где, поскольку препроцессор не делает. При попытке реализовать общие шаблоны через директивы препроцессору, то Вы закончите препроцессором, который должен быть столь же мощным как сам язык. Если Вы хотите к , обрабатывают Ваш код по-другому использование директива препроцессору , но если Вы просто хотите фрагмент кода, затем находят иначе, потому что препроцессор не был предназначен, чтобы сделать это.

4
ответ дан 30 November 2019 в 00:44
поделиться

Основным аргументом против создания pre-rocessor для C# является интеграция в Visual Studio: потребовало бы много усилий (если вообще возможный), чтобы заставить intellisense и новую фоновую компиляцию работать беспрепятственно.

Альтернативы должны использовать плагин производительности Visual Studio как ReSharper или CodeRush. Последний имеет - в меру моего знания - несопоставленная система шаблонной обработки и идет с превосходным рефакторинг инструмент.

Другой вещью, которая могла быть полезной в решении точных типов проблем, к которым Вы обращаетесь, является платформа AOP как PostSharp.
можно затем использовать пользовательские атрибуты для добавления общей функциональности.

3
ответ дан 30 November 2019 в 00:44
поделиться

Для получения названия в настоящее время выполняемого метода можно посмотреть на отслеживание стека:

public static string GetNameOfCurrentMethod()
{
    // Skip 1 frame (this method call)
    var trace = new System.Diagnostics.StackTrace( 1 );
    var frame = trace.GetFrame( 0 );
    return frame.GetMethod().Name;
}

, Когда Вы находитесь в методе набора свойств, имя является set_Property.

Используя ту же технику, можно также запросить исходный файл и строку/информацию о столбце.

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

1
ответ дан 30 November 2019 в 00:44
поделиться

Если бы я разрабатывал следующую версию C#, то я думал бы о каждой функции, имеющей автоматически включенную локальную переменную, содержащую название класса и название функции. В большинстве случаев оптимизатор компилятора вынул бы его.

я не уверен, что существует большая часть спроса на такую вещь все же.

0
ответ дан 30 November 2019 в 00:44
поделиться

@Jorge записал: Если Вы хотите обработать свой код по-другому использование директива препроцессору, но если Вы просто хотите фрагмент кода, затем находят иначе, потому что препроцессор не был предназначен, чтобы сделать это.

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

, Если это не надлежащее использование препроцессора, что мы должны назвать простой текстовой заменой, которая обычно должна происходить перед компиляцией?

0
ответ дан 30 November 2019 в 00:44
поделиться

Я думаю, что вы, возможно, упускаете одну важную часть проблемы при реализации INotifyPropertyChanged. Вашему потребителю нужен способ определения названия свойства. По этой причине имена ваших свойств должны быть определены как константы или статические строки, доступные только для чтения, чтобы потребителю не приходилось «угадывать» имена свойств. Если бы вы использовали препроцессор, как бы потребитель узнал, что такое строковое имя свойства?

public static string MyPropertyPropertyName
public string MyProperty {
    get { return _myProperty; }
    set {
        if (!String.Equals(value, _myProperty)) {
            _myProperty = value;
            NotifyPropertyChanged(MyPropertyPropertyName);
        }
    }
}

// in the consumer.
private void MyPropertyChangedHandler(object sender,
                                      PropertyChangedEventArgs args) {
    switch (e.PropertyName) {
        case MyClass.MyPropertyPropertyName:
            // Handle property change.
            break;
    }
}
1
ответ дан 30 November 2019 в 00:44
поделиться

Если вы готовы отказаться от C #, вы можете попробовать язык Boo , который имеет невероятно гибкую поддержку макросов через AST (Абстрактное синтаксическое дерево) манипуляции. Это действительно здорово, если вы можете отказаться от языка C #.

Дополнительные сведения о Boo см. В следующих связанных вопросах:

-1
ответ дан 30 November 2019 в 00:44
поделиться
Другие вопросы по тегам:

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