有没有办法通过C#代码获取您在类中使用的所有命名空间?

时间:2011-04-28 15:57:25

标签: c# reflection namespaces

有没有办法让List<string>包含名称空间/类中的所有“使用”?

例如

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Linq.Dynamic;
using System.Text.RegularExpressions;
using System.Reflection;
namespace MyNamespace.Other.Scripting
{

我会有一个包含“System”,“System.Text”,“System.Reflection”等的列表。

编辑:如下所示, 我正在使用这个http://kamimucode.com/Home.aspx/C-sharp-Eval/1 - C#评估器,我必须为TypeParser提供一个命名空间列表。问题是,我不会总是知道要放哪些。我正在使用C#中的一种简单的脚本语言,从中我将能够调用C#代码。我的另一种选择是在脚本语言中创建一个关键字,例如“using”,但我真的不想这样做。我希望能够选择一个C#对象,通过我的script.txt做任何我想做的事情,并且可以自由地使用它引用的命名空间。

我想在我的Xna Game引擎中使用它,能够编写可以执行C#的自定义脚本以及我的简单脚本函数。

3 个答案:

答案 0 :(得分:5)

这将适用于声明类的方法中的所有类型,但它不会为编译之前的文件中的所有类提供所有名称空间。这是不可能的,因为在编译之后,框架无法知道文件中的位置。

因此,如果每个文件有一个CLASS,这将起作用: 如果你遗漏了某些东西(我寻找字段和方法,也许某些东西没有被考虑在内,如果只是这样,那么就加入)

List<string> namespaces = new List<string>();

        var m = MethodInfo.GetCurrentMethod();

            foreach (var mb in m.DeclaringType.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic))
            {
                if (mb.MemberType == MemberTypes.Method && ((MethodBase)mb).GetMethodBody() != null)
                {

                    foreach (var p in ((MethodInfo)mb).GetMethodBody().LocalVariables)
                    {
                        if (!namespaces.Contains(p.LocalType.Namespace))
                        {
                            namespaces.Add(p.LocalType.Namespace);
                            Console.WriteLine(p.LocalType.Namespace);
                        }
                    }
                }
                else if (mb.MemberType == MemberTypes.Field) {
                    string ns = ((System.Reflection.FieldInfo)mb).FieldType.Namespace;
                    if (!namespaces.Contains(ns))
                    {                        
                        namespaces.Add(ns);
                        Console.WriteLine(ns);
                    }
                }
            }

我案例的示例输出:

System
System.Collections.Generic
System.Reflection
WindowsFormsApplication2
System.Linq.Expressions

答案 1 :(得分:1)

这是一个粗略的未经测试的尝试,让你开始:

IEnumerable<string> GetNamespacesUsed(string fileName)
{
    var lines = System.IO.File.ReadAllLines(fileName);
    var usingLines = lines.Where(
        x => x.StartsWith("using ") && !x.StartsWith("using ("));

    foreach (var line in usingLines)
    {
        if (line.Contains("="))
            yield return line.Substring(line.IndexOf("="), line.Length - 1);
        else
            yield return line.Substring(line.Length - 1);
    }
}

line.Length - 1可能不正确,最后切断分号。你需要测试它以找出它应该是什么。此外,这假设您的代码以相当标准的方式格式化。如果不是,它就行不通。

答案 2 :(得分:1)

您可以使用Mono Cecil从程序集中读取类定义,并获取每个方法中所有引用类型的列表。从那里,您可以提取名称空间列表(完全限定类型名称减去最后一部分)。