我试图通过反射调用静态抽象方法。在接口上声明静态抽象方法是一项预览功能,您可以在此处阅读更多内容。
当调用非静态抽象方法时,只需调用
TheType.GetMethod("MethodName").Invoke(null, null)
即可调用该方法,但是当在继承接口中声明静态抽象方法时,它似乎不会成为继承类型中的公共静态方法。一个例子:
我有一个接口
Entity
声明一个静态抽象方法 GetTableName()
:
public interface Entity
{
public static abstract string GetTableName();
}
然后有多种类型的Entity继承于
Entity
接口并实现GetTableName
方法:
static string Entity.GetTableName() => "[dbo].[SomeTable]";
尝试将
public
关键字添加到此实现时,会给出错误消息:
The modifier 'public' is not valid for explicit interface implementation
,我的理解是:接口已经声明了这个方法为public,所以去掉这个关键字。 (这是正确的吗?)
当尝试通过实现类型的反射来调用静态抽象方法时,找不到该方法并且
GetMethod()
返回 null
。在调试过程中,我可以看到该方法被声明为 Entity
类型的完整限定符,后跟方法名称“GetTableName”,因此我尝试以多种方式调用,例如:
var tableName = someType.GetMethod("GetTableName").Invoke(null, null);
var tableName = someType.GetMethod("FullQualifier.Entity.GetTableName").Invoke(null, null);
var tableName = someType.GetMethod("GetTableName", BindingFlags.NonPublic).Invoke(null, null);
var tableName = someType.GetMethod("GetTableName", BindingFlags.Static).Invoke(null, null);
遗憾的是,全部返回 null。经过进一步调试,该方法似乎被声明为 NonPublic。尽管如此,使用 NonPublic 绑定标志仍然没有效果。如何通过反射调用静态抽象方法?任何帮助将不胜感激。
不确定您的代码是如何组织的。以下代码运行良好:
为了获取类型,使用实现类的类型。
typeof(SomeTableEntity);
using System.Reflection;
namespace ConsoleApp1;
internal class Program
{
static void Main(string[] args)
{
var someType = typeof(SomeTableEntity);
var tableName = someType.GetMethod("GetTableName").Invoke(null, null);
Console.WriteLine(tableName);
}
}
public interface Entity
{
public static abstract string GetTableName();
}
public class SomeTableEntity : Entity
{
public static string GetTableName() => "[dbo].[SomeTable]";
}
根据@Sweeper的建议,查看这篇文章帮助我解决了我的问题;
var getTableNameMethod = (from method in SomeType.GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
select method).First()!;
var tableName = getTableNameMethod.Invoke(null, null);
不幸的是,我不知道为什么会这样,所以如果有人理解,请发表评论。