c#属性高于main [英] c# attribute over main

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

问题描述

有人问我如何打印

line no 1
line no 2
line no 3

不改变读取的主要方法

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.

只是好奇.

推荐答案

你的问题可以分解为对 Main 方法执行前后触发的钩子的搜索控制台应用程序.

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.

  • 第一个钩子是 Program 静态构造函数,即 保证Program类中执行before Main方法.

  • 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 的问题.

首先,考虑这个 StackOverflow 问题以准确了解 何时自定义属性构造函数被执行.这并不像乍一看那么简单.

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.

我们已经知道,自定义属性的 ctor 只会在您通过反射访问它时执行.因此,在您的示例中,简单的程序执行不会触发属性构造函数.但是,当您将 SomeAttribute 应用于 Main 方法时,为什么会出现断点?事实证明,Visual Studio 使用反射来找出主要方法并将调试器附加到您的应用程序.但此时没有控制台窗口.所以声明 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.

所以接下来的代码会产生不同的结果,这取决于你是否使用 VS 调试器运行它:

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");
    } 
}

如果你在没有调试器的情况下运行它(在 VS 默认配置中为 Ctrl + F5),你会看到,该程序终止并且没有窗口出现.当您使用调试器 (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旁边没有控制台窗口,只有win表单图标:

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#属性高于main的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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