What is the best way to define a static property which is defined once per sub-class?

后端 未结 3 1765
执笔经年
执笔经年 2021-01-12 18:56

I wrote the following console app to test static properties:

using System;

namespace StaticPropertyTest
{
    public abstract class BaseClass
    {
                 


        
3条回答
  •  难免孤独
    2021-01-12 19:37

    I just recently needed this same thing and came across this question. I think Jon's and Fried's ideas to use a Dictionary are on the right track but don't quite hit what I was looking for so I thought I'd show my own complete and very easy to extend implementation.

    public class TypeStaticProperty
    {
        T _defaultValue;
        Dictionary _values = new Dictionary();
    
        public TypeStaticProperty(T defalutValue = default)
        {
            _defaultValue = defalutValue;
        }
        
        public T Get(object caller)
        {
            lock (_values)
            {
                if (_values.TryGetValue(caller?.GetType(), out T val))
                    return val;
                else
                    return _defaultValue;
            }
        }
    
        public void Set(object caller, T val)
        {
            lock (_values)
                _values[caller?.GetType()] = val;
        }
    }
    

    And to demonstrate:

    class TestBaseClass
    {
        static TypeStaticProperty _property = new TypeStaticProperty();
        public int Property
        {
            get => _property.Get(this);
            set => _property.Set(this, value);
        }
    }
    
    class TestClass1 : TestBaseClass
    {
    }
    
    class TestClass2 : TestBaseClass
    {
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            TestClass1 test1a = new TestClass1();
            TestClass1 test1b = new TestClass1();
    
            test1a.Property = 1;
            test1b.Property = 2;
    
            TestClass2 test2a = new TestClass2();
            TestClass2 test2b = new TestClass2();
    
            test2a.Property = 3;
            test2b.Property = 4;
    
            Console.WriteLine($"test1a.Property = {test1a.Property}");
            Console.WriteLine($"test1b.Property = {test1b.Property}");
            Console.WriteLine($"test2a.Property = {test2a.Property}");
            Console.WriteLine($"test2b.Property = {test2b.Property}");
        }
    }
    

    Output:

    test1a.Property = 2
    test1b.Property = 2
    test2a.Property = 4
    test2b.Property = 4
    

    So while you still need a class instance to access and set the property, the value will always be the same across all instances of that precise type. (This includes generics too; Foo will be seen as a different type than Foo). This has the huge advantage over Fried's example in that you don't need to know at compile time the precise type whose "static" value you're looking for when accessing or setting.

    PS - For full disclosure, this was heavily inspired by the WPF source code, which uses a very similar pattern for DependencyProperty's and all kinds of other internal bells and whistles designed to improve performance and reduce memory footprint.

提交回复
热议问题