静态实例基础/派生类

时间:2014-03-20 10:58:21

标签: c# wpf converter derived-class ivalueconverter

我想在基类中编写一个静态实例属性并派生它,但我遇到了一些问题。

以下是基类的代码 - 我目前有:

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;
        }
    }
}

正如您所看到的,它主要用于WPF资源(如Converts),您通常在XAML中声明一个静态的键,以便为Codebehind Binding Creation获取此实例。

有了这个,应该可以编写来获取在XAML中声明的资源:

var fooConverter = FooConverter.Instance;

现在这在基类中可以正常工作。

  1. MethodBase.GetCurrentMethod()。DeclaringType.Name将 总是返回“ResourceInstance”,我希望得到派生的 类名,因为在我们的应用程序中,ClassName == ResourceKey

  2. Resharper,总是抱怨我访问的速度很快 派生类的静态属性,并希望我访问它 通过基类

  3. 以下是派生类的示例:

    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;
        }
    }
    

    希望你能提供帮助,谢谢。

3 个答案:

答案 0 :(得分:2)

我相信你的代码中存在轻微的谬误。想象一下,如果你有:

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

然后SomeConverter.InstanceSomeOtherConverter.Instance都是同一个对象(即ResourceInstance<IValueConverter>.Instance) - 只设置一次(无论哪个被称为第一个),这可能不是你想要的有

以下怎么样?稍微紧凑,但是。解决了上面的问题和b。工作:))

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;
       }
   }
}

然后将您的类型声明为

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

(我省略了BaseConverter因为这个实现可能没有什么用处。)

答案 1 :(得分:1)

不确定我是否理解你的问题,但我会这样做:

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
{
    ...
}

对T的约束确保该类将与模式class X : ResourceInstance<X>一起使用;这样,typeof(X)将始终为X

答案 2 :(得分:0)

静态成员完全特定于declaring class; subclasses不会获得单独的副本。这里唯一的例外是泛型;如果开放泛型类型声明静态字段,则该字段特定于组成闭合泛型类型的类型参数的确切组合;假设字段是在Foo上定义的,那么Foo会将单独的静态字段设置为Foo。