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

发布于 2024-11-04 02:24:05 字数 839 浏览 0 评论 0原文

有没有办法获得一个包含命名空间/类中所有“使用”的 List

例如,

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 游戏引擎中使用它,以便能够编写可以执行 C# 的自定义脚本以及我的简单脚本函数。

Is there any way to get a List<string> which contains all 'usings' within a namespace/class?

For instance

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
{

I would have a List with "System","System.Text", "System.Reflection", and so on.

EDIT: As a commented below,
I'm using this http://kamimucode.com/Home.aspx/C-sharp-Eval/1 - C# evaluator, and I have to feed the TypeParser with a list of namespaces. The thing is, I won't always know which ones to put. I'm working on a simple scripting language in C# and from it I'll be able to call C# code aswell. My other alternative is create a keyword such as "using" in the scripting language, but I really don't want to do that. I want to be able to pick an C# Object, do whatever I want with it through my script.txt, and be free to use its referenced namespaces.

I want to use it in my Xna Game engine, to be able to write custom scripts which can execute C# along with my simple script functions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

眼泪淡了忧伤 2024-11-11 02:24:05

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

因此,如果每个文件有一个类,则这将起作用:
如果您缺少某些内容(我寻找字段和方法,也许没有考虑某些内容,如果是这样,只需添加)

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

This will work for all types in methods of the declaring class, however it wont give all namespaces for all classes in the file where it was before compiling. That is impossible because after compilation the framework cannot know what was where in files.

So if you have one CLASS per file this will work:
If you are missing something (i look for fields and methods, maybe something is not taken in account, if that is so just add)

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

Sample output for my case:

System
System.Collections.Generic
System.Reflection
WindowsFormsApplication2
System.Linq.Expressions
嘿嘿嘿 2024-11-11 02:24:05

这是一个未经测试的粗略尝试,可以帮助您入门:

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 可能无法正确截断末尾的分号。您需要对其进行测试以找出它应该是什么。另外,这假设您的代码以相当标准的方式格式化。如果不是,那就行不通。

Here's a rough untested attempt to get you started:

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

The line.Length - 1 may not be correct to cut off the semicolon on the end. You'll need to test it to find out what it should be. Also, this assumes your code is formatted in a fairly standard way. If it's not, it won't work.

一直在等你来 2024-11-11 02:24:05

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

You can use Mono Cecil to read a class definition from an assembly and get a list of all the referenced types in each method. From there, you can extract a list of namespaces (fully qualified type name minus the last part).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文