From 4b8c4f19420317babd0f96e972c143fa7df37467 Mon Sep 17 00:00:00 2001 From: ig Date: Wed, 5 Apr 2023 17:43:27 +0200 Subject: [PATCH] add Utils/Reflection --- csharp/Lib/Utils/Reflection/DataMember.cs | 26 +++++++ csharp/Lib/Utils/Reflection/Field.cs | 49 +++++++++++++ csharp/Lib/Utils/Reflection/Member.cs | 33 +++++++++ csharp/Lib/Utils/Reflection/Method.cs | 52 ++++++++++++++ csharp/Lib/Utils/Reflection/Parameter.cs | 14 ++++ csharp/Lib/Utils/Reflection/Property.cs | 87 +++++++++++++++++++++++ 6 files changed, 261 insertions(+) create mode 100644 csharp/Lib/Utils/Reflection/DataMember.cs create mode 100644 csharp/Lib/Utils/Reflection/Field.cs create mode 100644 csharp/Lib/Utils/Reflection/Member.cs create mode 100644 csharp/Lib/Utils/Reflection/Method.cs create mode 100644 csharp/Lib/Utils/Reflection/Parameter.cs create mode 100644 csharp/Lib/Utils/Reflection/Property.cs diff --git a/csharp/Lib/Utils/Reflection/DataMember.cs b/csharp/Lib/Utils/Reflection/DataMember.cs new file mode 100644 index 000000000..5d2ed7eff --- /dev/null +++ b/csharp/Lib/Utils/Reflection/DataMember.cs @@ -0,0 +1,26 @@ +namespace InnovEnergy.Lib.Utils.Reflection; + +public abstract class DataMember : Member +{ + public abstract Object? Get(); + public abstract void Set(Object value); + + public abstract Boolean IsWriteable { get; } + public abstract Boolean IsReadable { get; } +} + +public static class DataMembers +{ + public static IEnumerable OfInstance(T instance) where T : notnull + { + return instance.GetDataMembers(); + } + + public static IEnumerable GetDataMembers(this T instance) where T : notnull + { + var fields = instance.GetFields(); + var props = instance.GetProperties(); + + return fields.Concat(props); + } +} \ No newline at end of file diff --git a/csharp/Lib/Utils/Reflection/Field.cs b/csharp/Lib/Utils/Reflection/Field.cs new file mode 100644 index 000000000..d4112f4c6 --- /dev/null +++ b/csharp/Lib/Utils/Reflection/Field.cs @@ -0,0 +1,49 @@ +using System.Reflection; +using static System.Reflection.BindingFlags; + +namespace InnovEnergy.Lib.Utils.Reflection; + +public class Field : DataMember +{ + private readonly Object? _Instance; + private readonly FieldInfo _FieldInfo; + + public override String Name => _FieldInfo.Name; + public override Type Type => _FieldInfo.FieldType; + + public override Boolean IsPublic => _FieldInfo.IsPublic; + public override Boolean IsPrivate => _FieldInfo.IsPrivate; + public override Boolean IsStatic => _FieldInfo.IsStatic; + + public override Boolean IsWriteable => true; + public override Boolean IsReadable => true; + + public override IEnumerable Attributes => _FieldInfo + .GetCustomAttributes(inherit: false) + .OfType(); + + internal Field(Object? instance, FieldInfo fieldInfo) + { + _Instance = instance; + _FieldInfo = fieldInfo; + } + + public override Object? Get() => _FieldInfo.GetValue(_Instance) ; + public override void Set(Object value) => _FieldInfo.SetValue(_Instance, value); +} + +public static class Fields +{ + public static IEnumerable GetFields(this T instance) where T : notnull + { + return instance + .GetType() + .GetFields(Instance | Static | Public | NonPublic) + .Select(fi => new Field(fi.IsStatic ? null : instance, fi)); + } + + public static IEnumerable OfInstance(T instance) where T : notnull + { + return instance.GetFields(); + } +} \ No newline at end of file diff --git a/csharp/Lib/Utils/Reflection/Member.cs b/csharp/Lib/Utils/Reflection/Member.cs new file mode 100644 index 000000000..24bcdf7a6 --- /dev/null +++ b/csharp/Lib/Utils/Reflection/Member.cs @@ -0,0 +1,33 @@ +namespace InnovEnergy.Lib.Utils.Reflection; + +public abstract class Member +{ + public abstract String Name { get; } + public abstract Type Type { get; } + + public abstract Boolean IsPublic { get; } + public abstract Boolean IsPrivate { get; } + public abstract Boolean IsStatic { get; } + + public abstract IEnumerable Attributes { get; } +} + + +public static class Members +{ + public static IEnumerable OfInstance(T instance) where T : notnull + { + return instance.GetMembers(); + } + + public static IEnumerable GetMembers(this T instance) where T : notnull + { + var fields = instance.GetFields(); + var props = instance.GetProperties(); + var methods = instance.GetMethods(); + + return fields + .Concat(props) + .Concat(methods); + } +} \ No newline at end of file diff --git a/csharp/Lib/Utils/Reflection/Method.cs b/csharp/Lib/Utils/Reflection/Method.cs new file mode 100644 index 000000000..a572ea97f --- /dev/null +++ b/csharp/Lib/Utils/Reflection/Method.cs @@ -0,0 +1,52 @@ +using System.Reflection; +using static System.Reflection.BindingFlags; + +namespace InnovEnergy.Lib.Utils.Reflection; + +public class Method : Member +{ + private readonly MethodInfo _MethodInfo; + private readonly Object? _Instance; + + public override Boolean IsPublic => _MethodInfo.IsPublic; + public override Boolean IsPrivate => _MethodInfo.IsPrivate; + public override Boolean IsStatic => _MethodInfo.IsStatic; + + public override String Name => _MethodInfo.Name; + public override Type Type => _MethodInfo.ReturnType; + + public override IEnumerable Attributes => _MethodInfo.GetCustomAttributes(); + + public IEnumerable Parameters => _MethodInfo + .GetParameters() + .Select(i => new Parameter(i)); + + internal Method(Object? instance, MethodInfo fieldInfo) + { + _MethodInfo = fieldInfo; + _Instance = instance; + } + + public Object? Invoke(params Object[] parameters) + { + return _MethodInfo.Invoke(_Instance, parameters); + } + + +} + + +public static class Methods +{ + public static IEnumerable GetMethods(this T instance) where T : notnull + { + return typeof(T) + .GetMethods(Instance | Static | Public | NonPublic) + .Select(mi => new Method(mi.IsStatic ? null : instance, mi)); + } + + public static IEnumerable OfInstance(T instance) where T : notnull + { + return instance.GetMethods(); + } +} \ No newline at end of file diff --git a/csharp/Lib/Utils/Reflection/Parameter.cs b/csharp/Lib/Utils/Reflection/Parameter.cs new file mode 100644 index 000000000..e48761bf6 --- /dev/null +++ b/csharp/Lib/Utils/Reflection/Parameter.cs @@ -0,0 +1,14 @@ +using System.Reflection; + +namespace InnovEnergy.Lib.Utils.Reflection +{ + public class Parameter + { + private readonly ParameterInfo _ParameterInfo; + + internal Parameter(ParameterInfo parameterInfo) => _ParameterInfo = parameterInfo; + + public Type Type => _ParameterInfo.ParameterType; + public String Name => _ParameterInfo.Name ?? ""; + } +} \ No newline at end of file diff --git a/csharp/Lib/Utils/Reflection/Property.cs b/csharp/Lib/Utils/Reflection/Property.cs new file mode 100644 index 000000000..e89716a46 --- /dev/null +++ b/csharp/Lib/Utils/Reflection/Property.cs @@ -0,0 +1,87 @@ +using System.Reflection; +using static System.Reflection.BindingFlags; + +namespace InnovEnergy.Lib.Utils.Reflection +{ + public class Property : DataMember + { + private readonly Object? _Instance; + private readonly PropertyInfo _PropertyInfo; + + internal Property(Object? instance, PropertyInfo propertyInfo) + { + _Instance = instance; + _PropertyInfo = propertyInfo; + } + + public override Boolean IsWriteable => _PropertyInfo.CanWrite; + public override Boolean IsReadable => _PropertyInfo.CanRead; + public override String Name => _PropertyInfo.Name; + public override Type Type => _PropertyInfo.PropertyType; + + public override Boolean IsPublic => _PropertyInfo.IsPublic(); + public override Boolean IsPrivate => _PropertyInfo.IsPrivate(); + public override Boolean IsStatic => _PropertyInfo.IsStatic(); + + public override IEnumerable Attributes => GetAttributes(); + + public override Object? Get() => _PropertyInfo.GetValue(_Instance); + public override void Set(Object value) => _PropertyInfo.SetValue(_Instance, value); + + public IEnumerable GetAttributes () where T : Attribute => _PropertyInfo + .GetCustomAttributes(inherit: false) + .OfType(); + + public Boolean HasAttribute () where T : Attribute => GetAttributes().Any(); + } + + + public static class Properties + { + public static IEnumerable GetProperties(this T instance) where T : notnull + { + return instance + .GetType() + .GetProperties(Instance | Static | Public | NonPublic) + .Where(p => p.GetIndexParameters().Length == 0) // no indexers please + .Select(pi => new Property(pi.IsStatic() ? null : instance, pi)); + } + + public static IEnumerable OfInstance(T instance) where T : notnull + { + return instance.GetProperties(); + } + } + + + internal static class PropertyInfoExtensions + { + public static Boolean IsStatic(this PropertyInfo i) + { + var getter = i.GetMethod; + var setter = i.SetMethod; + + return (getter is not null && getter.IsStatic) + || (setter is not null && setter.IsStatic); + } + + public static Boolean IsPublic(this PropertyInfo i) + { + var getter = i.GetMethod; + var setter = i.SetMethod; + + return (getter is not null && getter.IsPublic) + || (setter is not null && setter.IsPublic); + } + + public static Boolean IsPrivate(this PropertyInfo i) + { + var getter = i.GetMethod; + var setter = i.SetMethod; + + return (getter is not null && getter.IsPrivate) + || (setter is not null && setter.IsPrivate); + } + } + +} \ No newline at end of file