Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

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.

like image 203
Rand Random Avatar asked Mar 20 '14 10:03

Rand Random


People also ask

Can a derived class override a static method in a class?

Hence the answer is ‘No’. If a derived class defines a static method with the same signature as a static method in the base class, the method in the derived class is hidden by the method in the base class. The following are some important points for method overriding and static methods in Java.

What are the differences between instance and static methods in Java?

2) For instance (or non-static) methods, the method is called according to the type of object being referred, not according to the type of reference, which means method calls is decided at run time. 3) An instance method cannot override a static method, and a static method cannot hide an instance method.

Can We declare static methods with same signature in a subclass?

We can declare static methods with same signature in subclass, but it is not considered overriding as there won’t be any run-time polymorphism. Hence the answer is ‘No’. If a derived class defines a static method with same signature as a static method in base class, the method in the derived class hides the method in the base class.

Can We have two static methods with the same name?

We can have two or more static methods with the same name, but differences in input parameters. For example, consider the following Java program. Attention reader! Don’t stop learning now.


1 Answers

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).

like image 153
decPL Avatar answered Sep 28 '22 08:09

decPL