Re: Generics and static members

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



On Fri, 19 Sep 2008 09:27:25 -0700, Filip Zawada <fzawada@xxxxxxxxx> wrote:

[...]
The question is why can't I call a static method using generic
parameter?

I've specified that T is of type GoodBase<T>, so static methods from
GoodBase should be available by using generic parameter... Isn't
GoodBase<SomeEntity>.Met() actually the same as T.Met()? Why do I have
to repeat myself?

You don't. But, you also can't use T directly as the type.

It doesn't make sense to call static members on the type parameter. This is true regardless of whether or not the type parameter inherits a generic type or a non-generic one. Consider:

class A
{
public static void MethodA() { }
}

class B<T> : where T : A
{
public void MethodB()
{
T.MethodA();
}
}

One of two possible behaviors may be expected here.

First, it may be expected that if the class T reimplements MethodA(), you want the implementation in the most-derived class to be called. That is, if T is not A and has its own implementation of MethodA, you want _that_ implementation to be called rather than A.MethodA.

If this is the case, then it's not possible for the compiler to fulfill your intent, because it needs to know when it compiles the _generic_ class how to get at the method, and at that point the type parameter hasn't actually been resolved yet.

I suppose in theory, the compiler could generate some complex code to use reflection to determine at run-time the correct static method to call. But that could lead to a serious, non-obvious performance problem at best, and at worst could cause some subtle, hard-to-find bugs. It's wise for the language design to prohibit the use of a type parameter in that context.

Of course, there's nothing stopping you from writing such code explicitly. But in that case, it would be obvious looking at the code that's what you're doing.

Alternatively, maybe you always want to call A.MethodA. If that's the intent of the code, then you can get it to work by doing exactly that:

class B<T> : where T : A
{
public void MethodB()
{
A.MethodA();
}
}

Note that if T inherits a generic type, then you can use the same technique, supplying the type parameter:

class A<T>
{
public static void MethodA() { }
}

class B<T> : where T : A<T>
{
public void MethodB()
{
A<T>.MethodA();
}
}

In your own example, it would look like this:

public class DictModel<T>
: IDictModel<T>
where T : GoodBase<T>
{
public void Test()
{
GoodBase<SomeEntity>.Met(); //OK
SomeEntity.Met(); //OK
GoodBase<T>.Met(); //OK
}
}

That ensures that if the Met() method depends on the type parameter, that you actually get the implementation you desire (as opposed to calling GoodBase<SomeEntity>() in a class where you don't actually know that the type parameter T is "SomeEntity", which would be wrong).

Hope that helps.

Pete
.



Relevant Pages

  • Re: My First C# (warning - long post)
    ... add(entry, entry); ... public void makeAnimalSound ... AnimalNoiseGenerator noiseGenerator = dictionary.get ... one of this objects vs calling a static method. ...
    (comp.lang.cobol)
  • Re: New C# programmer questions
    ... static void Main ... an object to leave a static method for a non-static method? ... public void MyOtherMethod() ... // do the last of the things, time to exit program...how to exit? ...
    (microsoft.public.dotnet.languages.csharp)
  • RE: Timer and Random
    ... OnTimerEvent(object source, EventArgs e), method is not a static method, its ... > that go into this Picture Box. ... > public void Presentation_Load ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Static methods overridden !!
    ... However, if CowTest did have a matching static method, it wouldn't override ... My understanding of overriding is as follows. ... public void method1 ... Class DerivedOne extends Super { ...
    (comp.lang.java.programmer)
  • Re: Static methods overridden !!
    ... In Java overriding /is/ polymorphism. ... First off, as you also know, you can invoke any static method from any ... When it comes right down to it -- i.e. in terms of how the compiler treats ...
    (comp.lang.java.programmer)