如何在C#中通过运行时传递类型调用私有泛型方法

4

我在 .NET 3.5 中尝试了下面的代码,但 mi 为空。 如何调用私有泛型方法,以便可以在运行时传递类型参数? 如果将 SaveEntityGeneric 标记为 public,则此代码可以正常工作,但我不想将其公开,因为它仅在同一类中的其他方法中使用,以使用 GetType() 传递此类类型。

using System.Reflection;

public class Main1
{
    static void Main()
    {
        new Class1().Test();
    }
}

class Class1
{

    public void Test()
    {
        var mi = GetType().GetMethod("SaveEntityGeneric", BindingFlags.NonPublic);
        // why mi is null ?
        var gm = mi.MakeGenericMethod(GetType());
        gm.Invoke(this, null);
    }

    void SaveEntityGeneric<TEntity>()
    {
    }
}

1
这个问题包含了你所需要的一切:使用反射选择正确的泛型方法 - spender
1
@spender:那个问题涉及公共静态方法(不需要绑定标志来查找)。而这个问题涉及私有实例方法。它不是重复的。 - StriplingWarrior
1
@StriplingWarrior:同意。幸运的是,需要5个人来关闭一个问题。 - spender
2个回答

6
绑定标志在这个问题上很棘手。请使用BindingFlags.NonPublic | BindingFlags.Instance
var mi = GetType().GetMethod("SaveEntityGeneric", 
                             BindingFlags.NonPublic | BindingFlags.Instance);
var gm = mi.MakeGenericMethod(GetType());
gm.Invoke(this, null);

谢谢。当从ASP .NET MVC 2控制器(来自其他程序集)调用Test()方法时,GetMethod()仍然返回null。如果也从控制器调用,如何使其工作? - Andrus
1
@Andrus:非公共反射需要您在完全信任模式下运行,而ASP.NET默认情况下不会这样做(通常也不是一个好主意)。如果您理解并接受风险,请设置应用程序以完全信任模式运行。但是,您可能希望考虑改变方法来避免访问私有方法的需要。 - StriplingWarrior
我不明白如果对象调用自己的私有方法会有什么风险。没有反射,私有方法调用正常工作。这看起来像是.NET中的错误。GetMethod应该始终返回对象自己的私有方法。唯一的方法似乎是将这些方法公开,这很丑陋。 - Andrus
我尝试使用相同的代码从MVC控制器调用公共静态方法。 GetMethod在MVC中找不到它,但在控制台应用程序中找到了它。因此,在ASP .NET中也不支持公共静态方法调用吗? - Andrus
@Andrus:你的方法现在是公共的,但你的类仍然是私有的。如果你也将你的类设为公共的话,它应该可以工作了。 - StriplingWarrior
不,一切都是公开的。我在http://stackoverflow.com/questions/7406891/how-to-call-static-method-from-asp-net-mvc-controller-in-c中发布了一个新的代码示例,作为单独的问题。 - Andrus

0

只需将其设置为internal,这将防止在程序集外部使用该方法


如果在 EntityBase 对象的程序集中调用内部方法,则该方法将出现在 IntelliSense 中。我正在寻找一种方法使其变为私有,并从 MVC2 控制器调用公共方法,该公共方法调用此私有方法。 - Andrus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接