My Kingdom of Nouns for a Class Method

I'm really loving that the Castle Project wrote an ActiveRecord implementation. But one thing that I really miss from the Rails implementation is all the runtime dynamic missing_method goodness that comes from Ruby itself.

For example, consider the standard blog example, with Author.cs, Blog.cs, Post.cs and Comment.cs. All of these inherit from ActiveRecordBase (or one of the validating versions). However, in each child class, you have to put code like

        public static Author[] FindAll()
        {
            return (Author[]) ActiveRecordBase.FindAll(typeof(Author));
        }

        public static Author Find(int id)
        {
            return (Author) ActiveRecordBase.FindByPrimaryKey(typeof(Author), id);
        }

into each of the model classes. Naively, I want to put this code into the base class, like
        public static ActiveRecordBase[] FindAll()
        {
            return ActiveRecordBase.FindAll(typeof(this));
        }

but these are static methods -- no this to typeof. Furthermore, this post indicates that static in C# means "it can always be determined exactly, at compile time, what method will be called." So, if I have base.cs and Author.cs where Author.cs extends base.cs, and base has a static method foo, these two things are the same.
       Base.foo();
       Author.foo();

The compiler routes them both to Base.foo() at compile time. And if there were a good way to do this, the smart folks who wrote Castle ActiveRecord probably would have put it in the base class's implementation of FindAll.

What I really want is a class method, like what Ruby has in this example.

  class Base
    def self.from_where
      puts "Called from #{self.name}"
    end  
  end

  class Author < Base
  end

Note the convenient self that I can refer to, either for instances of the class, or the class itself in class methods. Now when I call the class methods like I did with the C# static methods, I get different (better) results.

  lego% irb
  >> load "base.rb"
  => true
  >> load "author.rb"
  => true
  
  >> Base.from_where
  Called from Base
  => nil
  
  >> Author.from_where
  Called from Author

So, back to my original problem. How do I do this in C#? I want DRY, so I don't want to cut'n'paste the same code into all the child classes, so I could go with what is already in the base class:

        public static ActiveRecordBase[] FindAll(Type type)

and I could call it like
        Author[] authors = (Author[]) Author.FindAll(typeof(Author));

Okay, kinda weird. "Author" seems to show up in a lot of places. And remember, because the compiler is statically determining that down to the base class static method, perhaps this is actually more clear (even though it is the same)
        Authors[] authors = (Author[]) ActiveRecordBase.FindAll(typeof(Author));

To get around (hide) all the casting and typeof's, I could bury this in an instance method in the base class
        public ActiveRecordBase[] FindAll()
        {
            return ActiveRecordBase.FindAll( typeof(this));
        }

and call it like
   me = new Author();
   Author[] authors = (Author[]) me.FindAll();

But that's just an awful way to confuse myself down the road -- the set of all authors should certainly not be available from a single instance of an author.

So, any C# ninjas know how to make actual class methods in C#?

Post new comment

The content of this field is kept private and will not be shown publicly.