Comments 43
class App { static App() {/* код до Main */} static void Main() {}}
Это то, что сразу пришло в голову.
Это то, что сразу пришло в голову.
+1
да, этот способ годится + есть много его вариаций )
может, еще какой-то знаете?
может, еще какой-то знаете?
0
Больше никакого не знаю, в том плане, что никогда не задумывался над вопросом, как можно выполнить функцию до Main().
С другой стороны, возможностей должно быть достаточно много. Если покопаться — можно попробовать найти те вещи, которая инфраструктура .NET так или иначе запускает до Main() и привязаться к ним. Но это надо смотреть, чем я сейчас и занимаюсь.
С другой стороны, возможностей должно быть достаточно много. Если покопаться — можно попробовать найти те вещи, которая инфраструктура .NET так или иначе запускает до Main() и привязаться к ним. Но это надо смотреть, чем я сейчас и занимаюсь.
0
так?
using System;
class Y
{
public Y()
{
Console.Write("0");
}
}
class X
{
private X(string s)
{
Console.Write(s);
}
public X() : this("_")
{
Console.Write("o");
}
Y y = new Y();
}
class App
{
static void Main()
{
X x = new X();
}
}
* This source code was highlighted with Source Code Highlighter.
0
Или так?
using System;
class Y
{
public Y()
{
Console.Write("0");
}
}
class Z
{
public Z()
{
Console.Write("_");
}
}
class X : Z
{
public X()
{
Console.Write("o");
}
Y y = new Y();
}
class App
{
static void Main()
{
X x = new X();
}
}
* This source code was highlighted with Source Code Highlighter.
+3
этот вариант правильный, предыдущий — нет, поскольку меняет код конструктора X.X
+1
:this("_") — это вызов конструктора, в принципе равноценно изменению кода метода. Насколько я понял, по условию это не допустимо.
0
А инициализацию Y можно менять? На Y y = new Y("");?
0
В общем, у меня случился такой код. Он работает и решает именно эту задачу.
using System;
using System.Threading;
using System.IO;
class Y
{
public Y()
{
Console.Write("0");
}
}
class X
{
public X()
{
Console.Write("o");
}
Y y = new Y();
}
class App
{
public class CustomWriter : TextWriter
{
private TextWriter c = null;
public CustomWriter()
{
c = Console.Out;
Console.SetOut(this);
}
public override System.Text.Encoding Encoding
{
get { return c.Encoding; }
}
public override void Write(object value)
{
c.Write(value);
}
public override void Write(string value)
{
c.Write(value);
if (value == "0")
c.Write("_");
}
}
static App()
{
Console.SetOut(new CustomWriter());
}
static void Main()
{
X x = new X();
Console.ReadLine();
}
}
* This source code was highlighted with Source Code Highlighter.
+3
да, можно принять как правильное ))
похоже, я недостаточно наложил ограничений на консольный вывод )
похоже, я недостаточно наложил ограничений на консольный вывод )
0
Да, надо было еще накладывать ограничение на недопустимость перенаправления стандартных потоков ввода-вывода, тогда этот код стал бы невозможен.
Но, в принципе, тут смотря что от задачи требуется. Мой код решает задачу, даже если накладывается ограничение на полную неизменность классов X и Y.
Но, в принципе, тут смотря что от задачи требуется. Мой код решает задачу, даже если накладывается ограничение на полную неизменность классов X и Y.
0
Вы и так уже наложили столько ограничений, что задачка определенно напоминает сферического коня в вакууме. кажется, вам просто пришел в голову некий вариант, а дальше вы усиленно пытаетесь всех к нему склонить, загоняя ограничениями в прокрустово ложе, хотя в таких задачах самое интересное обычно — неожиданный подход, как в посте выше. Примерно так же работают некоторые учителя в школах(и не только в школах), к сожалению.
+2
насчет сферического коня спорить не буду )
а смысл в такой задачке был в порядке вызова элементов — инициализатор производного типа, конструктор базового типа, конструктор производного типа. мне эта последовательность показалась неочевидной, на ней я и попытался построить задачку. то, что bobermaniac смог мои ограничения обойти — ему только в плюс, я считаю
а смысл в такой задачке был в порядке вызова элементов — инициализатор производного типа, конструктор базового типа, конструктор производного типа. мне эта последовательность показалась неочевидной, на ней я и попытался построить задачку. то, что bobermaniac смог мои ограничения обойти — ему только в плюс, я считаю
0
Добавляем в конец
class MyApp
{
static void Main()
{
Console.Write(«0_o»);
}
}
и компилим с опцией /main:MyApp
class MyApp
{
static void Main()
{
Console.Write(«0_o»);
}
}
и компилим с опцией /main:MyApp
0
А можно мне тоже какой-нибудь «этюд» запостить?
0
А, кстати, о вызове когда до Main не поведаете?
Еще будет замечательно, если поведаете, как вы это обнаружили и когда такие вызовы бывают нужны.
Еще будет замечательно, если поведаете, как вы это обнаружили и когда такие вызовы бывают нужны.
0
вот ниже показали еще способ
ну и применим тот же способ, которым решается этюд
по сути в этом и заключался исходный этюд для канала #c# )
ну и применим тот же способ, которым решается этюд
по сути в этом и заключался исходный этюд для канала #c# )
0
Ну такой вызов — это дурной тон. Код в конструкторе, да еще и эксепшн если вылетит, перехватить его не удастся. Жуть.
0
да, пожалуй
кстати, какого типа будет это неперехваченное исключение? )
кстати, какого типа будет это неперехваченное исключение? )
0
TargetInvocationException, как и любое другое исключение, выкинутое из конструктора.
0
MSDN говорит о TargetInvocationException: The exception that is thrown by methods invoked through reflection
Здесь у нас нет рефлексии вроде бы. Давайте сформулирую четче: речь идет о коде habrahabr.ru/blogs/net/77039/#comment_2241555
какое исключение получится в результате, если конструктор Z.Z() бросит, скажем, NullReferenceException?
Здесь у нас нет рефлексии вроде бы. Давайте сформулирую четче: речь идет о коде habrahabr.ru/blogs/net/77039/#comment_2241555
какое исключение получится в результате, если конструктор Z.Z() бросит, скажем, NullReferenceException?
0
В таком случае NullReferenceException и вылетит.
0
нет )
NullReferenceException будет обернут внутрь другого исключения
убедитесь сами
NullReferenceException будет обернут внутрь другого исключения
убедитесь сами
0
Эмм…
Выдает System.ApplicationException с полным стеком. Аналогично для NullReferenceException.
class Test
{
public Test() { throw new ApplicationException(); }
}
class App
{
static void Main()
{
try
{
new Test();
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().FullName);
}
Console.ReadLine();
}
}
* This source code was highlighted with Source Code Highlighter.
Выдает System.ApplicationException с полным стеком. Аналогично для NullReferenceException.
0
Ваш код радикально отличается от того, что приведен ниже )
смысл в том, что передаваемый там эксепшн нельзя перехватить обычными средствами, и приходится смотреть вывод консоли:
обратите внимание на то, что конструктор статический
смысл в том, что передаваемый там эксепшн нельзя перехватить обычными средствами, и приходится смотреть вывод консоли:
class Test
{
static Test() { throw new ApplicationException(); }
}
class App
{
static void Main()
{
Test test = new Test();
}
}
* This source code was highlighted with Source Code Highlighter.
обратите внимание на то, что конструктор статический
0
других, к сожалению, не знаю, но очень хочется узнать
0
кстати, есть еще один способ — через атрибуты. правда, в мелкософте об этом догадались, и все атрибуты, которые проверяются перед запуском, помечены как sealed (
так что только через подмену сборки со стандартными атрибутами
так что только через подмену сборки со стандартными атрибутами
0
Вот так вызовется до Main. Правда вставить "_" между Oо не получается пока.
class App
{
public static Z z = new Z();
static void Main()
{
X x = new X();
}
}
class App
{
public static Z z = new Z();
static void Main()
{
X x = new X();
}
}
+1
class App
{
[AutoStart()]
static void Main()
{
}
}
public class AutoStartAttribute: Attribute
{
public AutoStartAttribute()
{
Console.Beep();
}
}
{
[AutoStart()]
static void Main()
{
}
}
public class AutoStartAttribute: Attribute
{
public AutoStartAttribute()
{
Console.Beep();
}
}
0
у меня не срабатывает, фреймворк 3.5 SP1
смотрите habrahabr.ru/blogs/net/77039/#comment_2241758
пользовательские атрибуты создаются, когда их запрашивают
можно было бы унаследовать атрибут, который запрашивает сама среда выполнения (InAttribute, STAThreadAttribute), но, похоже, все они sealed
смотрите habrahabr.ru/blogs/net/77039/#comment_2241758
пользовательские атрибуты создаются, когда их запрашивают
можно было бы унаследовать атрибут, который запрашивает сама среда выполнения (InAttribute, STAThreadAttribute), но, похоже, все они sealed
0
Кхм, а у меня срабатывает, тоже SP1 3.5. По стеку видно, что internal код вызывает GetCustomAttributes… ну и в результате логичное создание экземпляра нашего атрибута
0
любопытно.
покажите тогда полностью код и параметры компилятора
у Вас один файл на вход компилятору подается?
покажите тогда полностью код и параметры компилятора
у Вас один файл на вход компилятору подается?
0
параметры дефолтные… я просто создал новый консольный проект
v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\ConsoleApplication2.exe /target:exe Program.cs Properties\AssemblyInfo.cs
v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\ConsoleApplication2.exe /target:exe Program.cs Properties\AssemblyInfo.cs
0
Ещё одно решение. Только если вставить Console.ReadLine() в Main, то работать не будет. Запускать нагляднее не из VS а из коммандной строки.
class Y {
public Y() {
Console.Write("0");
}
}
class X {
public X() {
Console.Write("o");
}
Y y = new Y();
}
class Z {
~Z() {
Console.Write("\r0_o");
}
}
class App {
static void Main() {
X x = new X();
}
static Z z = new Z();
}
* This source code was highlighted with Source Code Highlighter.
0
Sign up to leave a comment.
C#: Этюды, часть 2