簡體   English   中英

靜態實例基礎/派生類

[英]Static Instance Base/Derived class

我想在基類中編寫一個靜態實例屬性並派生它,但我遇到了一些問題。

這是基類的代碼 - 我目前有:

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中聲明一個靜態的鍵,以便為Codebehind Binding Creation獲取此實例。

有了這個,應該可以編寫來獲取在XAML中聲明的資源:

var fooConverter = FooConverter.Instance;

現在,這在基類中可以正常工作。

  1. MethodBase.GetCurrentMethod()。DeclaringType.Name將始終返回“ResourceInstance”,我希望得到派生類名,因為在我們的Application中ClassName == ResourceKey

  2. Resharper,總是抱怨我從派生類訪問靜態屬性的快速,並希望我通過基類訪問它

以下是派生類的示例:

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

希望你能幫助,thx。

我相信你的代碼中存在輕微的謬誤。 想象一下,如果你有:

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因為它可能沒有給出這個實現的目的)。

不確定我是否正確理解你的問題,但我會這樣做:

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

靜態成員完全特定於declaring class ; subclasses不會獲得單獨的副本。 這里唯一的例外是泛型; 如果開放泛型類型聲明靜態字段,則該字段特定於組成閉合泛型類型的類型參數的確切組合; 假設字段是在Foo上定義的,那么Foo會有單獨的靜態字段到Foo。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM