Отладка только конструкторов, не скомпилированных в режиме выпуска

Есть ли способ создать конструктор «Только отладка», который не скомпилирован в режиме выпуска?

Два решения, которые я нашел до сих пор:

  • окружает конструктор тегом #if DEBUG. Но это может быть довольно громоздко, если у вас много методов/конструкторов.
  • Используйте УсловныйАтрибут, но он не применяется ни к конструкторам, ни к методам, возвращающим что-либо, кроме void.

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

Спасибо за вашу помощь.

public class Foo
{

/// <summary>
/// Main constructor
/// </summary>
public Foo(){}

/// <summary>
/// Debug only constructor
/// </summary>
[Conditional("DEBUG")] //does not compile, wished behavior
internal Foo(bool dummy){}
}

РЕДАКТИРОВАТЬ

Как было указано Ченг Ченом и Эриком Филипсом ниже, этот вопрос был проблемой XY. Более широкая картина была такова: мой главный конструктор загружает тяжелые ресурсы из Интернета. Но я хотел отладить с помощью конструктора быстрой загрузки, загружающего фиктивные значения, тестируя только определенные функции. Я решил это, создав фиктивный класс вместо фиктивного конструктора рабочего класса. Возможно, есть лучшие решения этой проблемы.

Итак, суть такова:

  • Нет атрибута, работающего с конструкторами, подобными УсловныйАтрибут.
  • Вы можете окружить директиву компилятора #if DEBUG, чтобы предотвратить компиляцию определенного конструктора/метода в режиме выпуска. Вы также можете сгруппировать их в частичный класс для лучшей читабельности.
  • Но, если вам нужен такой конструктор, подумайте дважды, если нет других вариантов.
Почему Вам это нужно? Это проблема XY, то есть вы Думать, делая это, решит какую-то другую проблему, и вместо того, чтобы спрашивать, как решить эту проблему, вы хотите, чтобы мы решили проблему с помощью вашего решения.
Erik Philips 08.04.2019 03:07

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

XavierAM 08.04.2019 06:01

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

Erik Philips 08.04.2019 06:03

Загрузка набора данных со значениями по умолчанию вместо их фактических значений (собранных со всего Интернета)

XavierAM 08.04.2019 06:12
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
341
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

У тебя больше проблем, чем у ConditionalАтрибут.

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

Ошибка компилятора CS0592

Attribute 'attribute' is not valid on this declaration type. It is valid on 'type' declarations only.

When you define an attribute, you define what constructs it can be applied to by specifying an AttributeTargets value. In the following example, the MyAttribute attribute can be applied to interfaces only, because the AttributeUsage attribute specifies AttributeTargets.Interface. The error is generated because the attribute is applied to a class (class A).

Так уж получилось, что ConditionalAttribute определяется следующим образом:

 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]

Использование атрибутов (C#)

Determines how a custom attribute class can be used. AttributeUsageAttribute is an attribute you apply to custom attribute definitions. The AttributeUsage attribute enables you to control:

  • К какому атрибуту программных элементов можно применить. Если вы не ограничите его использование, атрибут может быть применен к любому из следующих элементов программы: сборке, модулю, полю, событию, методу, параметру, свойству, возврату, типу.
  • Можно ли применить атрибут к одному элементу программы несколько раз.
  • Наследуются ли атрибуты производными классами.

Итак, глядя на документацию, вы просто не можете использовать этот Атрибут на Конструктор.

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

#if (Справочник по C#)

When the C# compiler encounters an #if directive, followed eventually by an #endif directive, it compiles the code between the directives only if the specified symbol is defined.

public class Foo
{    
   public Foo() { }
   
#if DEBUG
   internal Foo2(Something something) { }
#endif
}

Или

public class Foo
{
#if DEBUG
   public Foo() { }
#else
   public Foo() { }
#endif
}

Спасибо, что заметили опечатку, поправил подпись конструктора.

XavierAM 08.04.2019 03:07

Ваш ответ на самом деле хорошо объясняет, почему он не работает, но мой вопрос был: есть ли обходной путь, чтобы получить поведение «ConditionalAttribute like» в конструкторах.

XavierAM 08.04.2019 03:09

@XavierAM да, используйте директиву компилятора, вы не можете изменить атрибут

TheGeneral 08.04.2019 03:10

Вы можете попробовать использовать классы частичный.

В основном вы разделяете класс на два файла. Один для обычной реализации, а другой для реализации Только отладка, которая заключена в директиву компилятора #if DEBUG.

// Foo.cs
public partial class Foo
{

   /// <summary>
   /// Main constructor
   /// </summary>
   public Foo(){}
}

// Foo.Debug.cs
public partial class Foo
{
  #if DEBUG

  /// <summary>
  /// Debug only constructor
  /// </summary>
  internal Foo(bool dummy){}

  #endif
}

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

Ответ принят как подходящий

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

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

public class Foo
{
    private Foo(){}
    private Foo(bool dummy){}

    public static Foo FromNormal() { }

#if DEBUG
    public static Foo FromDummy(bool dummy) { }
#endif
}

Вы правы, сделано в Edit. Кстати, я думаю, что вам не хватает возвращаемого типа для конструкторов Factory: public static Foo FromNormal() {} и public static Foo FromDummy(bool dummy) {}. Это опечатка?

XavierAM 15.04.2019 15:45

@XavierAM Спасибо, я набрал код прямо в браузере, допустил ошибку.

Cheng Chen 18.04.2019 04:33

Другие вопросы по теме