使用 C# 查看 MemberInfo 是否匹配 BindingFlags
See if MemberInfo matches BindingFlags using C#
我需要查看 MemberInfo
是否与特定的 BindingFlags
匹配。与此最接近的方法是 Type#GetMember(string, BindingFlags)
.
我找不到任何方法来做到这一点。
我想做这样的事情:
private List<MemberInfo> _members;
public IEnumerable<MemberInfo> GetMembers(BindingFlags flags)
{
foreach(var member in _members)
{
if(member.MatchesFlags(flags))
{
yield return member;
}
}
}
通过反射获得的 MemberInfo
的实际类型(例如通过在 Type
上调用 MemberInfo[]
GetMembers()
)是:
System.Reflection.RuntimeMethodInfo
System.Reflection.RuntimeConstructorInfo
System.Reflection.RuntimePropertyInfo
System.Reflection.RtFieldInfo
他们都独立地有属性BindingFlags
类型BindingFlags
。但是 属性 是 NonPublic。并且类型是 internal sealed
,这使得它们在普通代码中 无法访问 。这里 reflection
来拯救。要获得 MemberInfo
的 BindingFlags
,可以使用这样的扩展:
public static class MemberInfoExtension
{
private static readonly Dictionary<MemberInfo, BindingFlags> cache =
new Dictionary<MemberInfo, BindingFlags>();
private static readonly BindingFlags flags =
BindingFlags.Instance | BindingFlags.NonPublic;
public static BindingFlags GetFlags(this MemberInfo memberInfo)
{
if (cache.TryGetValue(memberInfo, out var bindingFlags))
return bindingFlags;
return cache[memberInfo] =
(BindingFlags)memberInfo.GetType()
.GetProperty("BindingFlags", flags)
.GetValue(memberInfo);
}
}
要查找与 BindingFlags
的匹配项,可以使用以下辅助方法:
public static class BindingFlagsExtension
{
public static bool Contains(this BindingFlags flags, BindingFlags bindingFlags) =>
(flags & bindingFlags) == bindingFlags;
public static bool MatchesExactly(this BindingFlags flags, BindingFlags bindingFlags) =>
flags == bindingFlags;
public static bool MatchesPartly(this BindingFlags flags, BindingFlags bindingFlags) =>
(flags & bindingFlags) != 0;
}
要测试解决方案,可以使用这样的 class:
private class DemoClass
{
private int PrivateInstanceField;
public string PublicInstanceField;
private bool PrivateInstanceProperty { get; }
public object PublicInstanceProperty { get; }
private void PrivateInstanceMethod() { }
public void PublicInstanceMethod() { }
private static int PrivateStaticField;
public static string PublicStaticField;
private static bool PrivateStaticProperty { get; }
public static object PublicStaticProperty { get; }
private static void PrivateStaticMethod() { }
public static void PublicStaticMethod() { }
}
然后运行:
static void Main(string[] args)
{
var type = typeof(DemoClass);
var members = type.GetMembers();
var flags = BindingFlags.Public | BindingFlags.Instance;
Console.WriteLine($"{type.Name} members with flags containing: {flags}\n");
foreach (var m in members.Where(m => m.GetFlags().Contains(flags)))
Print(m);
Console.WriteLine($"\n{type.Name} members with flags matching exactly: {flags}\n");
foreach (var m in members.Where(m => m.GetFlags().MatchesExactly(flags)))
Print(m);
Console.WriteLine($"\n{type.Name} members with flags matching partly: {flags}\n");
foreach (var m in members.Where(m => m.GetFlags().MatchesPartly(flags)))
Print(m);
}
private static void Print(MemberInfo memberInfo) =>
Console.WriteLine($"\t{memberInfo.GetType().Name} {memberInfo} - {memberInfo.GetFlags()}");
给出:
DemoClass members with flags containing: Instance, Public
RuntimeMethodInfo System.Object get_PublicInstanceProperty() - Instance, Public
RuntimeMethodInfo Void PublicInstanceMethod() - Instance, Public
RuntimeMethodInfo Boolean Equals(System.Object) - DeclaredOnly, Instance, Public
RuntimeMethodInfo Int32 GetHashCode() - DeclaredOnly, Instance, Public
RuntimeMethodInfo System.Type GetType() - DeclaredOnly, Instance, Public
RuntimeMethodInfo System.String ToString() - DeclaredOnly, Instance, Public
RuntimeConstructorInfo Void .ctor() - Instance, Public
RuntimePropertyInfo System.Object PublicInstanceProperty - Instance, Public
RtFieldInfo System.String PublicInstanceField - Instance, Public
DemoClass members with flags matching exactly: Instance, Public
RuntimeMethodInfo System.Object get_PublicInstanceProperty() - Instance, Public
RuntimeMethodInfo Void PublicInstanceMethod() - Instance, Public
RuntimeConstructorInfo Void .ctor() - Instance, Public
RuntimePropertyInfo System.Object PublicInstanceProperty - Instance, Public
RtFieldInfo System.String PublicInstanceField - Instance, Public
DemoClass members with flags matching partly: Instance, Public
RuntimeMethodInfo System.Object get_PublicInstanceProperty() - Instance, Public
RuntimeMethodInfo Void PublicInstanceMethod() - Instance, Public
RuntimeMethodInfo System.Object get_PublicStaticProperty() - Static, Public
RuntimeMethodInfo Void PublicStaticMethod() - Static, Public
RuntimeMethodInfo Boolean Equals(System.Object) - DeclaredOnly, Instance, Public
RuntimeMethodInfo Int32 GetHashCode() - DeclaredOnly, Instance, Public
RuntimeMethodInfo System.Type GetType() - DeclaredOnly, Instance, Public
RuntimeMethodInfo System.String ToString() - DeclaredOnly, Instance, Public
RuntimeConstructorInfo Void .ctor() - Instance, Public
RuntimePropertyInfo System.Object PublicInstanceProperty - Instance, Public
RuntimePropertyInfo System.Object PublicStaticProperty - Static, Public
RtFieldInfo System.String PublicInstanceField - Instance, Public
RtFieldInfo System.String PublicStaticField - Static, Public
我需要查看 MemberInfo
是否与特定的 BindingFlags
匹配。与此最接近的方法是 Type#GetMember(string, BindingFlags)
.
我找不到任何方法来做到这一点。
我想做这样的事情:
private List<MemberInfo> _members;
public IEnumerable<MemberInfo> GetMembers(BindingFlags flags)
{
foreach(var member in _members)
{
if(member.MatchesFlags(flags))
{
yield return member;
}
}
}
通过反射获得的 MemberInfo
的实际类型(例如通过在 Type
上调用 MemberInfo[]
GetMembers()
)是:
System.Reflection.RuntimeMethodInfo
System.Reflection.RuntimeConstructorInfo
System.Reflection.RuntimePropertyInfo
System.Reflection.RtFieldInfo
他们都独立地有属性BindingFlags
类型BindingFlags
。但是 属性 是 NonPublic。并且类型是 internal sealed
,这使得它们在普通代码中 无法访问 。这里 reflection
来拯救。要获得 MemberInfo
的 BindingFlags
,可以使用这样的扩展:
public static class MemberInfoExtension
{
private static readonly Dictionary<MemberInfo, BindingFlags> cache =
new Dictionary<MemberInfo, BindingFlags>();
private static readonly BindingFlags flags =
BindingFlags.Instance | BindingFlags.NonPublic;
public static BindingFlags GetFlags(this MemberInfo memberInfo)
{
if (cache.TryGetValue(memberInfo, out var bindingFlags))
return bindingFlags;
return cache[memberInfo] =
(BindingFlags)memberInfo.GetType()
.GetProperty("BindingFlags", flags)
.GetValue(memberInfo);
}
}
要查找与 BindingFlags
的匹配项,可以使用以下辅助方法:
public static class BindingFlagsExtension
{
public static bool Contains(this BindingFlags flags, BindingFlags bindingFlags) =>
(flags & bindingFlags) == bindingFlags;
public static bool MatchesExactly(this BindingFlags flags, BindingFlags bindingFlags) =>
flags == bindingFlags;
public static bool MatchesPartly(this BindingFlags flags, BindingFlags bindingFlags) =>
(flags & bindingFlags) != 0;
}
要测试解决方案,可以使用这样的 class:
private class DemoClass
{
private int PrivateInstanceField;
public string PublicInstanceField;
private bool PrivateInstanceProperty { get; }
public object PublicInstanceProperty { get; }
private void PrivateInstanceMethod() { }
public void PublicInstanceMethod() { }
private static int PrivateStaticField;
public static string PublicStaticField;
private static bool PrivateStaticProperty { get; }
public static object PublicStaticProperty { get; }
private static void PrivateStaticMethod() { }
public static void PublicStaticMethod() { }
}
然后运行:
static void Main(string[] args)
{
var type = typeof(DemoClass);
var members = type.GetMembers();
var flags = BindingFlags.Public | BindingFlags.Instance;
Console.WriteLine($"{type.Name} members with flags containing: {flags}\n");
foreach (var m in members.Where(m => m.GetFlags().Contains(flags)))
Print(m);
Console.WriteLine($"\n{type.Name} members with flags matching exactly: {flags}\n");
foreach (var m in members.Where(m => m.GetFlags().MatchesExactly(flags)))
Print(m);
Console.WriteLine($"\n{type.Name} members with flags matching partly: {flags}\n");
foreach (var m in members.Where(m => m.GetFlags().MatchesPartly(flags)))
Print(m);
}
private static void Print(MemberInfo memberInfo) =>
Console.WriteLine($"\t{memberInfo.GetType().Name} {memberInfo} - {memberInfo.GetFlags()}");
给出:
DemoClass members with flags containing: Instance, Public
RuntimeMethodInfo System.Object get_PublicInstanceProperty() - Instance, Public
RuntimeMethodInfo Void PublicInstanceMethod() - Instance, Public
RuntimeMethodInfo Boolean Equals(System.Object) - DeclaredOnly, Instance, Public
RuntimeMethodInfo Int32 GetHashCode() - DeclaredOnly, Instance, Public
RuntimeMethodInfo System.Type GetType() - DeclaredOnly, Instance, Public
RuntimeMethodInfo System.String ToString() - DeclaredOnly, Instance, Public
RuntimeConstructorInfo Void .ctor() - Instance, Public
RuntimePropertyInfo System.Object PublicInstanceProperty - Instance, Public
RtFieldInfo System.String PublicInstanceField - Instance, Public
DemoClass members with flags matching exactly: Instance, Public
RuntimeMethodInfo System.Object get_PublicInstanceProperty() - Instance, Public
RuntimeMethodInfo Void PublicInstanceMethod() - Instance, Public
RuntimeConstructorInfo Void .ctor() - Instance, Public
RuntimePropertyInfo System.Object PublicInstanceProperty - Instance, Public
RtFieldInfo System.String PublicInstanceField - Instance, Public
DemoClass members with flags matching partly: Instance, Public
RuntimeMethodInfo System.Object get_PublicInstanceProperty() - Instance, Public
RuntimeMethodInfo Void PublicInstanceMethod() - Instance, Public
RuntimeMethodInfo System.Object get_PublicStaticProperty() - Static, Public
RuntimeMethodInfo Void PublicStaticMethod() - Static, Public
RuntimeMethodInfo Boolean Equals(System.Object) - DeclaredOnly, Instance, Public
RuntimeMethodInfo Int32 GetHashCode() - DeclaredOnly, Instance, Public
RuntimeMethodInfo System.Type GetType() - DeclaredOnly, Instance, Public
RuntimeMethodInfo System.String ToString() - DeclaredOnly, Instance, Public
RuntimeConstructorInfo Void .ctor() - Instance, Public
RuntimePropertyInfo System.Object PublicInstanceProperty - Instance, Public
RuntimePropertyInfo System.Object PublicStaticProperty - Static, Public
RtFieldInfo System.String PublicInstanceField - Instance, Public
RtFieldInfo System.String PublicStaticField - Static, Public