有没有办法让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#的自定义脚本以及我的简单脚本函数。
答案 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从程序集中读取类定义,并获取每个方法中所有引用类型的列表。从那里,您可以提取名称空间列表(完全限定类型名称减去最后一部分)。