静态实例基/派生类

本文关键字:派生 实例 静态 | 更新日期: 2023-09-27 17:51:02

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

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

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资源,如转换,你通常在XAML中声明一个静态的键来获得这个实例,也用于代码后绑定创建。

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

var fooConverter = FooConverter.Instance;

显然,这在基类中工作得很好。

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

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

下面是一个派生类的例子:
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;
    }
}

希望你能帮忙,谢谢。

静态实例基/派生类

我认为你的代码中有一个小错误。想象一下,如果你有:

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

SomeConverter.InstanceSomeOtherConverter.Instance将是同一个对象(即ResourceInstance<IValueConverter>.Instance) -只设置一次(先调用的那个),这可能不是您想要的。

下面的内容如何?稍微不那么紧凑,但是a.解决了上面的问题,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,因为它在这个实现中可能没有什么用途)。

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

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

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