简体   繁体   English

静态实例基础/派生类

[英]Static Instance Base/Derived class

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. 正如您所看到的,它主要用于转换等WPF资源,您通常在XAML中声明一个静态的键,以便为Codebehind Binding Creation获取此实例。

With this it should be possible to just write to get the resource declared in XAML: 有了这个,应该可以编写来获取在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 MethodBase.GetCurrentMethod()。DeclaringType.Name将始终返回“ResourceInstance”,我希望得到派生类名,因为在我们的Application中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 Resharper,总是抱怨我从派生类访问静态属性的快速,并希望我通过基类访问它

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. 希望你能帮助,thx。

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 (ie ResourceInstance<IValueConverter>.Instance ) - set only once (whichever was called first), which is probably not what you've intended to have. 那么SomeConverter.InstanceSomeOtherConverter.Instance都是同一个对象(即ResourceInstance<IValueConverter>.Instance ) - 只设置一次(无论哪个被称为第一个),这可能不是你想要的。

How about the following? 以下怎么样? Slightly less compact, but a. 稍微紧凑,但是。 resolves the problem above and b. 解决了上面的问题和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). (我省略了BaseConverter因为它可能没有给出这个实现的目的)。

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> ; 对T的约束确保该类将与模式class X : ResourceInstance<X> ; this way, typeof(X) will always be X . 这样, typeof(X)将始终为X

static members are entirely specific to the declaring class ; 静态成员完全特定于declaring class ; subclasses do not get separate copies. subclasses不会获得单独的副本。 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; 如果开放泛型类型声明静态字段,则该字段特定于组成闭合泛型类型的类型参数的确切组合; ie Foo would have separate static fields to Foo, assuming the fields are defined on Foo. 假设字段是在Foo上定义的,那么Foo会有单独的静态字段到Foo。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM