Static Instance Base/Derived class

五迷三道 提交于 2019-12-22 05:49:18

问题


I would like to write a static instance property in a base class and derive this, but I am facing some problems.

Here is the code for the base class - I currently have:

public abstract class ResourceInstance<T>
{
    private static T _instance;
    public static T Instance
    {
        get
        {
            if (_instance != null)
                return _instance;

            var method = MethodBase.GetCurrentMethod();
            var declaringType = method.DeclaringType;
            if (declaringType != null)
            {
                var name = declaringType.Name;
                _instance = (T)Application.Current.TryFindResource(name);
            }

            return _instance;
        }
    }
}

As you can see its primary use is for WPF Resources like Converts, where you normally declare a key in XAML thats static to get this instance also for Codebehind Binding Creation.

With this it should be possible to just write to get the resource declared in XAML:

var fooConverter = FooConverter.Instance;

Now this works fine in the base class obviosly.

  1. the MethodBase.GetCurrentMethod().DeclaringType.Name will always return "ResourceInstance", and I hoped to get the derived class name, since in our Application the ClassName == ResourceKey

  2. Resharper, always complain about the fast that I am accessing a static property from the derived class and wants me to access it through the base class

Here is an example of a derived class:

public abstract class BaseConverter : ResourceInstance<IValueConverter>, IValueConverter
{
    public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }

    public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

public class FooConverter : BaseConverter
{
    public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return true;
    }
}

Hope you can help, thx.


回答1:


Not sure if I understand your question correctly, but I would do it like this:

public class ResourceInstance<T>
    where T : ResourceInstance<T> // To ensure correct usage
{
    private static T _instance;
    public static T Instance
    {
        get
        {
            if (_instance != null)
                return _instance;

            var name = typeof(T).Name;
            _instance = (T)Application.Current.TryFindResource(name);

            return _instance;
        }
    }
}

public class FooConverter : ResourceInstance<FooConverter>, IValueConverter
{
    ...
}

The constraint on T ensures that the class will be used with the pattern class X : ResourceInstance<X>; this way, typeof(X) will always be X.




回答2:


I believe there is a slight fallacy in your code. Imagine if you have:

SomeConverter : BaseConverter { ... }
SomeOtherConverter : BaseConverter { ... }

then both SomeConverter.Instance and SomeOtherConverter.Instance would be the same object (i.e. ResourceInstance<IValueConverter>.Instance) - set only once (whichever was called first), which is probably not what you've intended to have.

How about the following? Slightly less compact, but a. resolves the problem above and b. works :)

public abstract class ResourceInstance<TBase, TActual>
{
   private static TBase _instance;
   public static TBase Instance
   {
       get
       {
           if (_instance == null)
              _instance = (T)Application.Current.TryFindResource(typeof(TActual).Name);

           return _instance;
       }
   }
}

and then declare your types as

SomeConverter : ResourceInstance<IValueConverter, SomeConverter>, IValueConverter { ... }

(I've omitted BaseConverter as it probably has little purpose given this implementation).




回答3:


static members are entirely specific to the declaring class; subclasses do not get separate copies. The only exception here is generics; if an open generic type declares static fields, the field is specific to that exact combination of type arguments that make up the closed generic type; i.e. Foo would have separate static fields to Foo, assuming the fields are defined on Foo.



来源:https://stackoverflow.com/questions/22530820/static-instance-base-derived-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!