tags:

views:

148

answers:

3

I've got an abstract class like this;

public abstract PropertyBase
{
    public static System.Type GetMyType()
    {
      return !!!SOME MAGIC HERE!!!
    }
}

I'd like to subclass it, and when I call the static GetMyType(), I'd like to return the subclass's type. So if I declare a subtype;

public class ConcreteProperty: PropertyBase {}

then when I call

var typeName = ConcreteProperty.GetMyType().Name;

I expect 'typeName' to be set to "ConcreteProperty." I suspect there's no way to do it, but I'm interested if anyone out there knows a way to get this info.

(The particular problem I'm trying to solve is the verbosity of dependency properties in WPF; I'd love to be able to do something like this;

class NamedObject : DependencyObject
{
    // declare a name property as a type, not an instance.
    private class NameProperty : PropertyBase<string, NamedObject> { }

    // call static methods on the class to read the property
    public string Name
    {
        get { return NameProperty.Get(this); }
        set { NameProperty.Set(this, value); }
    }
}

And I almost have an implementation, but I can't quite get the info I need out of my NameProperty class.)

+4  A: 

You can partially achieve (1-level of inheritance deep) using generics:

class PropertyBase<T>
{
    public static Type GetMyType() { return typeof (T); }
}

// the base class is actually a generic specialized by the derived class type
class ConcreteProperty : PropertyBase<ConcreteProperty> { /* more code here */ }

// t == typeof(ConcreteProperty)
var t = ConcreteProperty.GetMyType();
LBushkin
Note that this only works one level, if you descend from ConcreteProperty, it will still return ConcreteProperty from GetMyType.
Lasse V. Karlsen
That is true. And one of the limitations of this approach. But it may still help with the dependency property example of the OP.
LBushkin
This is certainly the best approach I've seen so far; you create the reference to the type be re-quoting it in the type parameters. For my example, this works nicely, although it imposes a little more typing on the developer. Anyway, this is the best yet, and very helpful. Thanks.
Steve Cooper
+2  A: 

The subclassing bit will not work, because a static method is tied to a type. It is a method of a type, not a method of an instance. The subtype does not contain the static methods of a base type, because they are different types and the static method is tied to the base type. Even though the compiler might allow you to call a static method of a base class as through a derived class, it will in reality call the method from the base class. It's just syntax sugar. For the same reason you cannot "override" static methods in subclasses because it would make little sense.

Vilx-
A: 

Just wondering why would need to do something like this?

var typeName = ConcreteProperty.GetMyType().Name;

Anyhow you know the type while calling the method, you can simply do this as well..

   var typeName = typeof(ConcreteProperty).Name;

Just in case you need to do this, you can use "shadowing" to override the implementation of base class in child class.

public class ConcreteProperty : PropertyBase {

        public new static Type GetMyType {
           //provide a new implementation here
        }
    }
Amby
Unfortunately in my example code I've simplified it to reduce it to the essential problem, and this would be solvable in the way you've described. What my solution requires, though, is the ability to ask, for any subclass of PropertyBase, 'what's your actual type'. The way that, for example, calling `this.GetType()` always gets the actual type rather than a base type.
Steve Cooper