Есть ли способ создать конструктор «Только отладка», который не скомпилирован в режиме выпуска?
Два решения, которые я нашел до сих пор:
В идеале атрибут, идентичный условному, но с расширенной областью действия, был бы потрясающим.
Спасибо за вашу помощь.
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. Более широкая картина была такова: мой главный конструктор загружает тяжелые ресурсы из Интернета. Но я хотел отладить с помощью конструктора быстрой загрузки, загружающего фиктивные значения, тестируя только определенные функции. Я решил это, создав фиктивный класс вместо фиктивного конструктора рабочего класса. Возможно, есть лучшие решения этой проблемы.
Итак, суть такова:
Хорошо, точка принята. Итог: мне нужен конструктор с быстрой загрузкой для отладки, тогда как мой обычный конструктор требует много ресурсов. Но я не хочу, чтобы этот конструктор был доступен где-либо еще. Внутреннего может быть достаточно
Ну и зачем вам быстро загружающийся конструктор (вы все равно рассказываете о своей попытке решения, чем о самой проблеме). Что вы делаете, что требует другого конструктора во время отладки?
Загрузка набора данных со значениями по умолчанию вместо их фактических значений (собранных со всего Интернета)
У тебя больше проблем, чем у Conditional
Атрибут.
У вас не может быть двух Конструкторы с одинаковой подписью. В любом случае, помимо этого (поскольку я уверен, что это всего лишь опечатка), давайте посмотрим на документацию:
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)]
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:
Итак, глядя на документацию, вы просто не можете использовать этот Атрибут на Конструктор.
Однако вы можете использовать Директива компилятора:
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
}
Спасибо, что заметили опечатку, поправил подпись конструктора.
Ваш ответ на самом деле хорошо объясняет, почему он не работает, но мой вопрос был: есть ли обходной путь, чтобы получить поведение «ConditionalAttribute like» в конструкторах.
@XavierAM да, используйте директиву компилятора, вы не можете изменить атрибут
Вы можете попробовать использовать классы частичный.
В основном вы разделяете класс на два файла. Один для обычной реализации, а другой для реализации Только отладка, которая заключена в директиву компилятора #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 Спасибо, я набрал код прямо в браузере, допустил ошибку.