开发者

"Magic" constants in C# like PHP has?

I am building a logging control for a C# project and would like to be able to call it with the name of the current source code File, Line, Class, Function, etc. PHP uses "magic constants" that have all of this info: http://php.net/manual/en/language.constants.predefined.php but I don't see anything like that in the C# compiler language.

Am I looking for some开发者_开发百科thing that doesn't exist?


Using the StackTrace/StackFrame classes, you can have your control find out where it's been called from, rather than passing it that information:

private static StringBuilder ListStack(out string sType)
{
  StringBuilder sb = new StringBuilder();
  sType = "";

  StackTrace st = new StackTrace(true);
  foreach (StackFrame f in st.GetFrames())
  {
    MethodBase m = f.GetMethod();
    if (f.GetFileName() != null)
    {
      sb.AppendLine(string.Format("{0}:{1} {2}.{3}",
        f.GetFileName(), f.GetFileLineNumber(),
        m.DeclaringType.FullName, m.Name));

      if (!string.IsNullOrEmpty(m.DeclaringType.Name))
        sType = m.DeclaringType.Name;
    }
  }

  return sb;
}

(I used this code to get the call stack of the currently executed method, so it does more than you asked for)


The StackTrace/StackFrame classes will give you quite a bit of this, though they can be quite expensive to construct.


You can ask the system for a stack trace, and you can use reflection. Details are coming.

__LINE__ 
__FILE__ 
__DIR__ 
__FUNCTION__  (does not really exist in C#) 
__CLASS__
__METHOD__
__NAMESPACE__

This is a start:

  • http://www.csharp-examples.net/reflection-callstack/
  • http://www.csharp-examples.net/reflection-calling-method-name/
  • Assembly.GetExecutingAssembly().FullName
  • System.Reflection.MethodBase.GetCurrentMethod().Name

You will get better information in Debug (non-optimized) build. PhP might always have access to all that stuff, but it ain't the fastest gun on this planet. Play with it and let me know what is missing.


There are methods to get this type of data. It depends on what data you want.

__CLASS__ : If you want the current classname you'll need to use reflection.

__LINE__ : I'm not sure what "The current line number of the file" means, I'll take a guess and say it's how many lines in the file. That can be done by opening the file and doing a line count. This can be done via the File class, the FileInfo class may also work.

__DIR__ :Getting the directory of the file is done by using the DirectoryInfo class.

__FUNCTION__ and __METHOD__: Function name (method name), this can be retrieved via reflection.

__NAMESPACE__ :Namespace an be retrieved via reflection


Using Type, the best you can really do is get information about the current class. There is no means to get the file (though you should generally stick to one class per file), nor line number, nor function using Type.

Getting a type is simple, for example, this.getType(), or typeof(MyClass).

You can get the more specific details by generating a StackTrace object and retrieving a StackFrame from it, but doing so repeatedly is a bad idea.

I think a more important question is perhaps: why do you need them? For trace debugging, your output is supposedly temporary, so whether it reflects an accurate line number or not shouldn't matter (in fact, I rarely ever include a line number in trace debugging). Visual Studio is also very useful as a true step debugger. What do you really need File, Class, Function, and Line Number for?

Edit: For error checking, use exceptions like they're meant to be used: for exceptional (wrong) cases. The exception will generate a stack trace pointing you right at the problem.


Many of the previous responders have provided excellent information; however, I just wanted to point out that accessing the StackFrame is exorbitantly expensive and probably shouldn't be done except for special cases. Those cases being an extremely chatty verbose mode for debugging corner cases or error logging and for an error you probably already have an Exception instance which provides the StackTrace. Your best performance will be as Bring S suggested by using Type. Also as another design consideration logging to the console can slow your application down by several orders of magnitude depending on the volume of data to display. So if there is a console sink having the writer operating on a worker thread helps tremendously.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜