Re: Generics and static members
- From: "Peter Duniho" <NpOeStPeAdM@xxxxxxxxxxxxxxxx>
- Date: Fri, 19 Sep 2008 11:39:10 -0700
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
.
- References:
- Generics and static members
- From: Filip Zawada
- Generics and static members
- Prev by Date: EndReceiveFrom throws exception.
- Next by Date: Re: Generics and static members
- Previous by thread: Generics and static members
- Next by thread: Re: Generics and static members
- Index(es):
Relevant Pages
|