2010-10-28 14 views
5

Dado un objeto Tipo en .NET, ¿es posible obtener el nombre del código fuente? Sé que esto solo estaría disponible en las compilaciones de depuración y está bien, también sé que puedo usar el objeto StackTrace para obtener el nombre de archivo de un marco en particular en una pila de llamadas, pero eso no es lo que quiero.Obtener el nombre de archivo del código fuente de un tipo en depuración compilación

¿Pero es posible para mí obtener el nombre de archivo del código fuente para un System.Type dado?

+0

posible duplicado de [¿Cómo obtener el nombre del archivo de origen y el número de línea de un miembro de tipo?] (Http://stackoverflow.com/questions/126094/how-to-get-the-source-file-name -and-the-line-number-of-a-type-member) –

+0

¿Por qué lo quieres? La mayoría de las razones que puedo pensar se resolverían con herramientas como servidores de Symbol/Source ... –

Respuesta

3

Teniendo en cuenta que al menos C# admite declaraciones de clase parciales (por ejemplo, public partial class Foo en dos archivos de código fuente), ¿qué significaría "el nombre de archivo de código fuente para un determinado System.Type"? Si una declaración de tipo se extiende a través de múltiples archivos de código fuente dentro del mismo ensamblado, no hay un solo punto en el código fuente donde comienza la declaración.

@Darin Dimitrov: Esto no parece ser un duplicado de "¿Cómo obtener el nombre del archivo de origen y el número de línea de un miembro de tipo?" para mí, ya que se trata de un tipo miembro, mientras que esta pregunta es sobre un tipo.

+0

Estábamos haciendo una refacturación masiva de espacios de nombres y cosas así en mi empresa y quería escribir una prueba unitaria que verificara si el espacio de nombres correspondía a la ubicación del archivo. Ya hemos terminado, así que ya no lo necesito más, pero la pregunta sigue en pie, ¿debe haber alguna forma de acceder al pdb y obtener esta información? En cuanto a las clases parciales, entonces deberíamos poder obtener ambos nombres de archivo. –

+0

@Michael sería 'string []' :-D –

+0

@Simon_Weaver Bueno, duh, pero el OP pidió "*** el *** nombre de archivo del código fuente para un System.Type dado" :-) –

3

he utilizado un código como éste para obtener un archivo de origen y el número de línea del método que se está ejecutando:

//must use the override with the single boolean parameter, set to true, to return additional file and line info 

System.Diagnostics.StackFrame stackFrame = (new System.Diagnostics.StackTrace(true)).GetFrames().ToList().First(); 

//Careful: GetFileName can return null even though true was specified in the StackTrace above. This may be related to the OS on which this is running??? 

string fileName = stackFrame.GetFileName(); 
string process = stackFrame.GetMethod().Name + " (" + (fileName == null ? "" : fileName + " ") + fileLineNumber + ")"; 
3

me encontré con un problema similar. Necesitaba encontrar el nombre de archivo y el número de línea de un método específico con solo el tipo de la clase y el nombre del método. Estoy en una vieja versión mono .NET (unidad 4.6). Utilicé la biblioteca cecil, proporciona algún ayudante para analizar su pbd (o mdb para mono) y analiza los símbolos de depuración. https://github.com/jbevain/cecil/wiki

Para un tipo y método dado:

System.Type myType = typeof(MyFancyClass); 
string methodName = "DoAwesomeStuff"; 

me encontré con esta solución:

Mono.Cecil.ReaderParameters readerParameters = new Mono.Cecil.ReaderParameters { ReadSymbols = true }; 
Mono.Cecil.AssemblyDefinition assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(string.Format("Library\\ScriptAssemblies\\{0}.dll", assemblyName), readerParameters); 

string fileName = string.Empty; 
int lineNumber = -1; 

Mono.Cecil.TypeDefinition typeDefinition = assemblyDefinition.MainModule.GetType(myType.FullName); 
for (int index = 0; index < typeDefinition.Methods.Count; index++) 
{ 
    Mono.Cecil.MethodDefinition methodDefinition = typeDefinition.Methods[index]; 
    if (methodDefinition.Name == methodName) 
    { 
     Mono.Cecil.Cil.MethodBody methodBody = methodDefinition.Body; 
     if (methodBody.Instructions.Count > 0) 
     { 
      Mono.Cecil.Cil.SequencePoint sequencePoint = methodBody.Instructions[0].SequencePoint; 
      fileName = sequencePoint.Document.Url; 
      lineNumber = sequencePoint.StartLine; 
     } 
    } 
} 

Sé que es un poco tarde :) pero espero que esto ayude a alguien!

Cuestiones relacionadas