13
public class BusinessObjects<O>
    where O : BusinessObject
{
    void SomeMethod()
    {
        var s = O.MyStaticMethod(); // <- How to do this?
    }
}

public class BusinessObject
{
    public static string MyStaticMethod()
    {
        return "blah";
    }
}

Is there a correct object oriented approach to accomplishing this or will I need to resort to reflection?

EDIT: I went too far in trying to oversimplify this for the question and left out an important point. MyStaticMethod uses reflection and needs the derived type to return the correct results. However, I just realized another flaw in my design which is that I can't have a static virtual method and I think that's what I would need.

Looks like I need to find another approach to this problem altogether.

gdoron
  • 147,333
  • 58
  • 291
  • 367
Brandon Moore
  • 8,590
  • 15
  • 65
  • 120

3 Answers3

14

You can't access a static method through a generic type parameter even if it's constrained to a type. Just use the constrained class directly

var s = BusinessObject.MyStaticMethod();

Note: If you're looking to call the static method based on the instantiated type of O that's not possible without reflection. Generics in .Net statically bind to methods at compile time (unlike say C++ which binds at instantiation time). Since there is no way to bind statically to a static method on the instantiated type, this is just not possible. Virtual methods are a bit different because you can statically bind to a virtual method and then let dynamic dispatch call the correct method on the instantiated type.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • Guess I didn't provide enough info. Check for an updated question momentarily... – Brandon Moore Feb 05 '12 at 02:53
  • @BrandonMoore updated my answer a bit to be a bit more detailed on the limitations – JaredPar Feb 05 '12 at 02:56
  • Yep, and since I can't have a virtual static method that sort of kills my approach. I think reflection is going to be the way to go. – Brandon Moore Feb 05 '12 at 03:04
  • I think I could have equally marked this as the answer but since I can only pick one I went with the one that doesn't make me think as much when I read it :) – Brandon Moore Feb 05 '12 at 03:15
  • @BrandonMoore definitely pick whichever one you think most accurately answers your question :) – JaredPar Feb 05 '12 at 03:16
  • They both accurately answer it. I'm curious though, you said C++ binds at instantiation time so does that mean this 'would' be possible in C++? – Brandon Moore Feb 05 '12 at 03:26
  • @BrandonMoore im fairly certain this would be possible in C++. – JaredPar Feb 05 '12 at 03:38
  • @BrandonMoore: The answer you currently marked as accepted is simply incorrect. You should choose this answer as the accepted one. – Daniel Hilgarth May 02 '13 at 10:49
  • @DanielHilgarth It looks like you're disputing whether static members are inherited between types based on some syntactic sugar that allows you to write code that 'looks' like inheritance. Would you say that's accurate of your argument, and if not then on what basis are you challenging roken's answer? – Brandon Moore May 04 '13 at 20:26
  • @BrandonMoore: Static members are inherited. roken claims otherwise and he is wrong. My comments to his answer contain links and quotes that prove this. – Daniel Hilgarth May 05 '13 at 07:24
  • @DanielHilgarth Sorry, I agree with roken that it's not true inheritance, but just some syntactic sugar. I also respect JaredPar's opinion and he didn't seem to have any problem with my choosing roken's answer. I think we're just going to have to agree to disagree on this one. – Brandon Moore May 08 '13 at 21:04
  • @BrandonMoore: Or you could read the official documentation which clearly states that it is inheritance. But then, I don't really care if you agree or not. And about Jared not disagreeing with you choosing the other answer: This doesn't mean anything. Have a look at the edit history of the chosen answer. Up to a few days ago it contained *completely wrong* information. It said that you couldn't call `Foo.MyStaticMethod`. That's just plain wrong. Obviously, Jared simply didn't care. – Daniel Hilgarth May 09 '13 at 09:36
  • @BrandonMoore: Hm, it looks like I do care after all, if you agree or not. The C# specification states in §1.6: *Classes support **inheritance** and **polymorphism** [...]*. Please note how this are two distinct properties. §1.6.4 states that *a class implicitly contains all members of its base class, except for the instance and static constructors [...] of the base class*. It doesn't exclude static methods or properties here. §3.4.4 and §10.3.3 state the same in more detail – Daniel Hilgarth May 09 '13 at 10:04
4

The reason you can't reference the static member like this:

O.MyStaticMethod(); 

Is because you don't know what type O is. Yes, it inherits from BusinessObject, but static members are not inherited between types, so you can only reference MyStaticMethod from BusinessObject.

roken
  • 3,946
  • 1
  • 19
  • 32
  • @DanielHilgarth, removed the errant example. Although the compiler will allow you to call the static method via a derived class, it is still true that static members are not inherited. The IL generated will actually be calling the method on the base class. And again, although the compiler allows it, referencing static methods from the derived type is bad form and can lead to confusion, especially when using creational patterns. – roken May 02 '13 at 15:18
  • You are correct in your comment when you say that the compiler will change `Foo.MyStaticMethod()` to `BusinessObject.MyStaticMethod()`. However, this doesn't make your answer correct. It is simply not correct, that you can only reference (did you mean "call"?) `MyStaticMethod` from `BusinessObject`. – Daniel Hilgarth May 02 '13 at 15:21
  • O is a generic type parameter. As we've already agreed, there is no inheritance of static methods between types, thus you cannot expect to be able to call this method on some type O that is derived from BusinessObject in this context. The compiler team could have provided some magic here as they did in the explicit-type-name case, but [thankfully] they did not. I will agree my answer isn't as verbose as it could be, but I still wouldn't call it incorrect. – roken May 02 '13 at 15:33
  • I disagree that there is no inheritance of static methods. If there would be no inheritance, `Foo.MyStaticMethod()` indeed would be invalid. Furthermore, if you want to provide a different implementation of `MyStaticMethod` on `Foo` you would have to use the [`new`](http://msdn.microsoft.com/en-us/library/51y09td4%28v=vs.71%29.aspx#vclrfnew_newmodifier) modifier which is used *to explicitly hide a member inherited from a base class*. The example for the new modifier even contains an example with static members. – Daniel Hilgarth May 02 '13 at 15:39
  • The only thing you don't have with static methods is dynamic dispatch, i.e. polymorphism. My guess is that *that* is the actual reason why it's illegal to do what the OP tried to do, because without dynamic dispatch this is always the same as using the class the generic argument is constraint to (`BusinessObject` in this example). – Daniel Hilgarth May 02 '13 at 15:41
2

If you are forcing O to inherit from BusinessObject, why not just call it like this:

void SomeMethod()
{
    var s = BusinessObject.MyStaticMethod(); // <- How to do this?
}
gdoron
  • 147,333
  • 58
  • 291
  • 367
ose
  • 4,065
  • 2
  • 24
  • 40