sdu*_*ooy 88 .net c# reflection
假设以下假设的继承层次结构:
public interface IA
{
int ID { get; set; }
}
public interface IB : IA
{
string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使用反射并进行以下调用:
typeof(IB).GetProperties(BindingFlags.Public | BindingFlags.Instance)
Run Code Online (Sandbox Code Playgroud)
只会产生接口的属性IB,即" Name".
如果我们要对以下代码进行类似的测试,
public abstract class A
{
public int ID { get; set; }
}
public class B : A
{
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
该调用typeof(B).GetProperties(BindingFlags.Public | BindingFlags.Instance)将返回PropertyInfo" ID"和" Name" 的对象数组.
有没有一种简单的方法来查找接口的继承层次结构中的所有属性,如第一个示例中所示?
myt*_*thz 108
我已经将@Marc Gravel的示例代码调整为有用的扩展方法,封装了类和接口.它还首先添加了接口属性,我认为这是预期的行为.
public static PropertyInfo[] GetPublicProperties(this Type type)
{
if (type.IsInterface)
{
var propertyInfos = new List<PropertyInfo>();
var considered = new List<Type>();
var queue = new Queue<Type>();
considered.Add(type);
queue.Enqueue(type);
while (queue.Count > 0)
{
var subType = queue.Dequeue();
foreach (var subInterface in subType.GetInterfaces())
{
if (considered.Contains(subInterface)) continue;
considered.Add(subInterface);
queue.Enqueue(subInterface);
}
var typeProperties = subType.GetProperties(
BindingFlags.FlattenHierarchy
| BindingFlags.Public
| BindingFlags.Instance);
var newPropertyInfos = typeProperties
.Where(x => !propertyInfos.Contains(x));
propertyInfos.InsertRange(0, newPropertyInfos);
}
return propertyInfos.ToArray();
}
return type.GetProperties(BindingFlags.FlattenHierarchy
| BindingFlags.Public | BindingFlags.Instance);
}
Run Code Online (Sandbox Code Playgroud)
Dou*_*las 68
Type.GetInterfaces 返回展平的层次结构,因此不需要递归下降.
使用LINQ可以更简洁地编写整个方法:
public static IEnumerable<PropertyInfo> GetPublicProperties(this Type type)
{
if (!type.IsInterface)
return type.GetProperties();
return (new Type[] { type })
.Concat(type.GetInterfaces())
.SelectMany(i => i.GetProperties());
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*ell 15
接口层次结构是一种痛苦 - 它们并不真正"继承",因为你可以拥有多个"父母"(因为想要更好的术语).
"扁平化"(再次,不是正确的术语)层次结构可能涉及检查接口实现的所有接口并从那里开始工作......
interface ILow { void Low();}
interface IFoo : ILow { void Foo();}
interface IBar { void Bar();}
interface ITest : IFoo, IBar { void Test();}
static class Program
{
static void Main()
{
List<Type> considered = new List<Type>();
Queue<Type> queue = new Queue<Type>();
considered.Add(typeof(ITest));
queue.Enqueue(typeof(ITest));
while (queue.Count > 0)
{
Type type = queue.Dequeue();
Console.WriteLine("Considering " + type.Name);
foreach (Type tmp in type.GetInterfaces())
{
if (!considered.Contains(tmp))
{
considered.Add(tmp);
queue.Enqueue(tmp);
}
}
foreach (var member in type.GetMembers())
{
Console.WriteLine(member.Name);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)