Search code examples
c#pythonclass-method

Python-style classmethod for C#?


Is there a way to do what classmethod does in Python in C#?

That is, a static function that would get a Type object as an (implicit) parameter according to whichever subclass it's used from.

An example of what I want, approximately, is

class Base:
    @classmethod
    def get(cls, id):
        print "Would instantiate a new %r with ID %d."%(cls, id)

class Puppy(Base):
    pass

class Kitten(Base):
    pass

p = Puppy.get(1)
k = Kitten.get(1)

the expected output being

Would instantiate a new <class __main__.Puppy at 0x403533ec> with ID 1.
Would instantiate a new <class __main__.Kitten at 0x4035341c> with ID 1.

(same code on codepad here.)


Solution

  • In principle, you could write something like this:

    class Base
    {
        public static T Get<T>(int id)
            where T : Base, new()
        {
            return new T() { ID = id };
        }
    
        public int ID { get; set; }
    }
    

    Then you could write var p = Base.Get<Puppy>(10). Or, if you were feeling masochistic, you could write Puppy.Get<Puppy>(10) or even Kitty.Get<Puppy> ;) In all cases, you have to pass in the type explicitly, not implicitly.

    Alternatively, this works too:

    class Base<T> where T : Base<T>, new()
    {
        public static T Get(int id)
        {
            return new T() { ID = id };
        }
    
        public int ID { get; set; }
    }
    
    class Puppy : Base<Puppy>
    {
    }
    
    class Kitten : Base<Kitten>
    {
    }
    

    You still need to pass the type back up to the base class, which allows you to write Puppy.Get(10) as expected.

    But still, is there a reason to write it like that when var p = new Puppy(10) is just as concise and more idiomatic? Probably not.