如何从列表中获取名称?
e.g
static void Main()
{
var methods = new List<Func<int>>();
methods.Add(() => new ThisCss().useThis(0));
// Output ThisCss here from methods
// i.e Console.WriteLine(methods[0].ClassName).. or something like that
}
class ThisCss
{
public int useThis(int num)
{
return 0;
}
}
所以只是为了澄清我想从函数列表的0索引中获取类的名称。所以在这种情况下,它将是'ThisCss'。
您正在尝试将函数调用分解为表达式树。
你不能这样做一个普通的老Func
,但你可以这样做到System.Linq.Expressions.Expression
。
using System;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Reflection;
public class ThisCss
{
public int useThis(int num)
{
return 0;
}
}
public class Program
{
public static Type ExtractClassType(Expression<Func<int>> methodCall)
{
if (methodCall.Body.NodeType == ExpressionType.Call)
{
MethodCallExpression memberExpression = (System.Linq.Expressions.MethodCallExpression)methodCall.Body;
MethodInfo memberInfo = memberExpression.Method;
return memberInfo.DeclaringType;
}
else
{
throw new InvalidOperationException("Unable to extract a method call from this expression");
}
}
public static void Main()
{
var methods = new List<Expression<Func<int>>>();
methods.Add(() => new ThisCss().useThis(0));
var type = ExtractClassType(methods[0]);
Console.WriteLine("{0}", type);
}
}
Func<...>
是一个delegate
,所有delegate
实例派生自System.Delegate
,它具有返回Method
的System.Reflection.MethodInfo
属性,其中包含有关被调用的实际CLR方法的元信息,包括其包含类型/类(CLR中没有自由函数,所有函数方法)。
试试这个:
foreach( Func<Int32> f in methods ) {
MethodInfo mi = f.Method;
String typeName = mi.DeclaringType.FullName;
Console.WriteLine( typeName + "." + mi.Name );
}
请注意,如果您引用匿名函数或Lambda函数,那么真正的DeclaringType
将是C#编译器生成的类型,具有不可预测或意外的名称(您可以使用CAL反汇编工具(如Ildasm
,ILSpy或RedGate Reflector)查看。
如果您可以更改返回类型,那么'元组'怎么样?
var methods = new List<Tuple<string, Func<int>>>();
methods.Add(new Tuple<string, Func<int>>(nameof(ThisCss), () => new ThisCss().useThis(0)));
methods.Add(new Tuple<string, Func<int>>(nameof(ThisCss2), () => new ThisCss2().useThis(0)));
var className = methods[0].Item1;
在C#7.0中
var methods = new List<(string ClassName, Func<int> Func)>();
methods.Add((nameof(ThisCss), () => new ThisCss().useThis(0)));
methods.Add((nameof(ThisCss2), () => new ThisCss2().useThis(0)));
var className = methods[0].ClassName;