c# 反射 - 访问静态类上的对象属性

本文关键字:对象 属性 静态类 反射 访问 | 更新日期: 2023-09-27 18:33:04

我使用这篇文章中的代码在应用程序中实现功能切换,它运行良好。 但是,现在我的功能不是直接的布尔值开/关,每个功能都有两个布尔值:一个用于常规设置,另一个用于仅适用于用户子集的设置。 我一直在尝试更新代码来处理这个问题,我发现我对反射和访问器的基本理解不足。

我正在使用下面的代码在 LINQPad 中进行测试 - 基本上,与上面提到的帖子相比,我所做的只是尝试将 TestFeatureToggle 从布尔值更改为类型 MultiToggle 但我正在努力设置或获取 MultiToggle 对象的布尔属性的值。 我在

return (bool)multiToggleProperty.GetValue(null,null);

"非静态方法需要一个目标"。 这是有道理的,因为 MultiToggle 上的属性是非静态的。 但是,我没有这些对象的实例,也不明白如何从静态类中获取一个。

任何帮助将不胜感激。我的直觉告诉我这可能是不可能的!

        void Main()
    {
        var exampleFeatureToggles = new List<FeatureToggle>
        {
            new FeatureToggle {Description = "Test", Id = 1, IsActive = true, Name = "TestFeatureToggle"}
        };
        FeatureToggles.SetFeatureToggles(exampleFeatureToggles);
        Console.WriteLine(FeatureToggles.GetFeatureToggleSetting("TestFeatureToggle"));
    }
    public class FeatureToggle
    {
        public string Description { get; set; }
        public int Id { get; set; }
        public bool IsActive { get; set; }
        public string Name { get; set; }
    }
    public class MultiToggle
    {
        public bool DefaultValue { get; private set; }
        public bool OtherValue { get; private set; }
    }
    public static class FeatureToggles
    {
        //public static bool TestFeatureToggle { get; private set; }
        public static MultiToggle TestFeatureToggle { get; private set; }
        public static void SetFeatureToggles(List<FeatureToggle> toggles)
        {
            if (toggles == null) return;
            var properties = typeof(FeatureToggles).GetProperties(BindingFlags.Public | BindingFlags.Static);
            // All properties must be set to false to prevent a property staying true when deleted from the database
            foreach (var property in properties)
            {
                var multiToggleProperties = typeof(MultiToggle).GetProperties();
                foreach (var multiToggleProperty in multiToggleProperties)
                {
                    multiToggleProperty.SetValue(new MultiToggle(), false, null);
                }
            }
            foreach (var toggle in toggles)
            {
                foreach (var property in properties)
                {
                    if (property.Name.ToLower() == toggle.Name.ToLower())
                    {
                        Type tProp = property.GetType();
                        var multiToggleProperties = typeof(MultiToggle).GetProperties();
                        foreach (var multiToggleProperty in multiToggleProperties)
                        {
                            Console.WriteLine(multiToggleProperty);
                            multiToggleProperty.SetValue(new MultiToggle(), toggle.IsActive, null);
                        }
                    }
                }
            }
        }
        public static bool GetFeatureToggleSetting(string propertyName)
        {
            var properties = typeof(FeatureToggles).GetProperties(BindingFlags.Public | BindingFlags.Static);
            foreach (var property in properties)
            {
                if (property.Name.ToLower() == propertyName.ToLower())
                {
                    Type tProp = property.GetType();
                    var multiToggleProperties = typeof(MultiToggle).GetProperties();
                    Console.WriteLine(multiToggleProperties);
                    foreach (var multiToggleProperty in multiToggleProperties)
                    {
                        Console.WriteLine(multiToggleProperty);
                        return (bool)multiToggleProperty.GetValue(null, null);
                    }
                }
            }
            return false;
        }
    }

c# 反射 - 访问静态类上的对象属性

这个想法就在那里,但你基本上"只是超越了目标"。您收到"非静态方法需要目标"错误,因为您尝试在静态属性的值中获取属性的值,而没有先获取静态属性的值(多么拗口(。即你要去:

get static property type -> get instance property type -> get value of property from static property.

DefaultValueOtherValue 是实例属性,因此您首先需要实例对象,然后才能获取其值。我做了一些调整,只是为了向您展示如何设置静态属性并从静态属性中获取值。您应该能够从那里调整它:

void Main()
{
    var exampleFeatureToggles = new List<FeatureToggle>
    {
        new FeatureToggle {Description = "Test", Id = 1, IsActive = true, Name = "TestFeatureToggle"}
    };
    FeatureToggles.SetFeatureToggles(exampleFeatureToggles);
    Console.WriteLine(FeatureToggles.GetFeatureToggleSetting("TestFeatureToggle"));
}
public class FeatureToggle
{
    public string Description { get; set; }
    public int Id { get; set; }
    public bool IsActive { get; set; }
    public string Name { get; set; }
}
public class MultiToggle
{
    public bool DefaultValue { get; private set; }
    public bool OtherValue { get; private set; }
}
public static class FeatureToggles
{
    //public static bool TestFeatureToggle { get; private set; }
    public static MultiToggle TestFeatureToggle { get; private set; }
    public static void SetFeatureToggles(List<FeatureToggle> toggles)
    {
        if (toggles == null) return;
        var properties = typeof(FeatureToggles).GetProperties(BindingFlags.Public | BindingFlags.Static);
        // All properties must be set to false to prevent a property staying true when deleted from the database
        foreach (var property in properties)
        {
            // first change: set the _property_, not multiToggleProperty
            property.SetValue(null, new MultiToggle());
        }
        foreach (var toggle in toggles)
        {
            foreach (var property in properties)
            {
                if (property.Name.ToLower() == toggle.Name.ToLower())
                {
                    Type tProp = property.GetType();
                    var multiToggleProperties = typeof(MultiToggle).GetProperties();
                    // second change: create a nee instance, set the values, then set that value on the static property
                    var newMultiToggle = new MultiToggle();
                    property.SetValue(null, newMultiToggle);
                    foreach (var multiToggleProperty in multiToggleProperties)
                    {
                        Console.WriteLine(multiToggleProperty);
                        multiToggleProperty.SetValue(newMultiToggle, toggle.IsActive, null);
                    }
                }
            }
        }
    }
    public static bool GetFeatureToggleSetting(string propertyName)
    {
        var properties = typeof(FeatureToggles).GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
        foreach (var property in properties)
        {
            if (property.Name.ToLower() == propertyName.ToLower())
            {
                Type tProp = property.GetType();
                // third change: get the static value first, then get the value from the properties on that instance.
                var value = property.GetValue(null);
                var multiToggleProperties = typeof(MultiToggle).GetProperties();
                Console.WriteLine(multiToggleProperties);
                foreach (var multiToggleProperty in multiToggleProperties)
                {
                    Console.WriteLine(multiToggleProperty);
                    return (bool)multiToggleProperty.GetValue(value, null); //
                }
            }
        }
        return false;
    }
}