如何从List <Func <Int32 >>中提取类名

问题描述 投票:0回答:3

如何从列表中获取名称?

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'。

c# .net
3个回答
0
投票

您正在尝试将函数调用分解为表达式树。

你不能这样做一个普通的老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);
    }
}

0
投票

Func<...>是一个delegate,所有delegate实例派生自System.Delegate,它具有返回MethodSystem.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)查看。


0
投票

如果您可以更改返回类型,那么'元组'怎么样?

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;
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.