在主要的C#属性 [英] c# attribute over main

查看:151
本文介绍了在主要的C#属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人问我一个问题,我们如何可以打印

Someone asked me a question as to how we can print

line no 1
line no 2
line no 3

在不改变其内容主要方法

Without changing a main method which reads

static void Main(string[] args)
{
    Console.WriteLine("line no 2");
}

现在一种方法是有控制台应用程序的多个入口点。不过,我试过另一种方法肚里如下:

Now one approach was to have multiple entry points for the console application. However I tried another approach which goes as follows :

class Program
{
    [Some]
    static void Main(string[] args)
    {
        Console.WriteLine("line no 2");
    }
}
class SomeAttribute : Attribute
{
    public SomeAttribute()
    {
        Console.WriteLine("line no 1");
    }
    ~SomeAttribute()
    {
        Console.WriteLine("line no 3");
    }
}

当我申请一个断点每个的的WriteLine 的,我能看到的方式工作,但是,同样是没有反映在控制台上。

When I apply a breakpoint on each of the WriteLine, I am able to see that the approach works, however, the same isn't reflected on the console.

只是好奇。

推荐答案

您是问题可以细分为搜索挂钩,这是之前触发后控制台应用程序的方法执行。

You're problem can be broken down into the search of the hooks, which are triggered before and after Main method execution of the console application.


  • 第一钩子是程序静态构造函数,这是的保证执行的方法程序类。

  • First hook is a Program static constructor, which is guarantee to execute before Main method in Program class.

二是事件 ProcessExit 一个的AppDomain ,其中的时发生的默认应用程序域的父进程退出的。您可以使用静态构造函数订阅此事件。

Second is an event ProcessExit of a AppDomain, which "Occurs when the default application domain's parent process exits". You can use static constructor to subscribe to this event.

class Program
{
    static Program()
    {
        Console.WriteLine("line no 1");

        AppDomain.CurrentDomain.ProcessExit += 
                                          (s, a) => Console.WriteLine("line no 3");
    }

    static void Main(string[] args)
    {
        Console.WriteLine("line no 2");
    }
}

打印:

line no 1
line no 2
line no 3


下一部分将是相当长的。我会尽量解释什么是你的问题与 SomeAttribute 的问题。

首先,考虑这个问题,计算器确切地知道时自定义属性构造执行。这不是那么简单,因为它可能乍一看。

First of all, consider this StackOverflow question to know exactly when custom attributes constructors are executed. This isn't so simple, as it might seem at first glance.

我们已经知道,自定义属性的构造函数只会被执行,当你将通过反射访问它。因此,在你的例子简单的程序执行将不会触发属性构造。但是,为什么你遇到断点,当你申请 SomeAttribute 的方法?事实证明,这视觉工作室使用反思,找出主要方法和调试器附加到应用程序。但是,在这一点上没有控制台窗口。因此声明 Console.WriteLine 是无用的,要产生效果。此外,它似乎要禁止所有的下一个语句控制台输出。

As we already know, ctor of custom attribute will only be executed, when you will access it via reflection. So in you example simple program execution won't trigger attribute constructor. But why do your breakpoint hit, when you apply SomeAttribute to Main method? It turns out, that visual studio uses reflexion to find out main method and attach a debugger to your application. But there is no console window at that point. So statement Console.WriteLine is useless and produce to effect. Moreover, it seems to block all next statements to console output.

因此​​,下code会产生不同的结果,这取决于你与运行与调试与否:

So next code will produce different results, depending if you run it with VS debugger or not:

class Program
{
    [MyAttribute]
    static void Main()
    {

    }
}

class MyAttribute : Attribute
{
    public MyAttribute()
    {
        MessageBox.Show("MyAttribute ctor");
    } 
}

如果您没有调试器中运行( Ctrl键 + F5 在VS默认配置),你会看到,该程序终止,并没有窗户出现。当您使用调试器执行它( F5 ),你会看到

If you run it without debugger (Ctrl + F5 in VS default configuration), you'll see, that program terminates and no windows appear. When you execute it with debugger (F5) you'll see

和无控制台窗口旁边VS,止赢形式的图标:

and no console window next to VS, only win forms icon:

正如我前面,当你尝试写入控制台时,有没有人,那么所有其他呼叫 Console.WriteLine 不影响您的控制台描述应用。这就是为什么你可以看到任何控制台消息,即使你在构造函数中一步一个断点。

As I've described earlier, when you try to write to console when there is no one, then all other calls to Console.WriteLine doesn't affect your console application. That's why you can see any console messages, even if you step a breakpoint in the constructor.

这篇关于在主要的C#属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆