tags:

views:

2712

answers:

5

I was hoping to do something like this, but it appears to be illegal in C#:


public Collection MethodThatFetchesSomething<T>()
    where T : SomeBaseClass
{
    return T.StaticMethodOnSomeBaseClassThatReturnsCollection();
}

I get a compile-time error: "'T' is a 'type parameter', which is not valid in the given context."

Given a generic type parameter, how can I call a static method on the generic class? The static method has to be available, given the constraint.

A: 

As of now, you can't. You need a way of telling the compiler that T has that method, and presently, there's no way to do that. (Many are pushing Microsoft to expand what can be specified in a generic constraint, so maybe this will be possible in the future).

James Curran
The problem is that because generics are provided by the runtime, this would probably mean a new CLR version - which they've (largely) avoided since 2.0. Maybe we're due a new one, though...
Marc Gravell
+1  A: 

It sounds like you're trying to use generics to work around the fact that there are no "virtual static methods" in C#.

Unfortunately, that's not gonna work.

Brad Wilson
I'm not - I'm working above a generated DAL layer. The generated classes all inherit from a base class, which has a static FetchAll method. I'm trying to reduce code duplication in my repository class with a "generic" repository class - a lot of repeating code, except for the concrete class used.
Remi Despres-Smyth
Then why don't you just call SomeBaseClass.StaticMethod...() ?
Brad Wilson
Sorry, I didn't explain myself well in the previous comment. FetchAll is defined on the base, but implemented on the derived classes. I need to call it on the derived class.
Remi Despres-Smyth
If it is a static method, then it is both defined and implemented by the base. There is no such thing as virtual/abstract static method in C#, and no override for such. I suspect you have simply re-declared it, which is very different.
Marc Gravell
Yes, you're right - I had made invalid assumptions here. Thanks for the discussion, it's helped put me on the right track.
Remi Despres-Smyth
+1  A: 

The only way of calling such a method would be via reflection, However, it sounds like it might be possible to wrap that functionality in an interface and use an instance-based IoC / factory / etc pattern.

Marc Gravell
+8  A: 

In this case you should just call the static method on the constrainted type directly. C# (and the CLR) do not support virtual static methods. So T.StaticMethodOnSomeBaseClassThatReturnsCollection can be no different than SomeBaseClass.StaticMethodOnSomeBaseClassThatReturnsCollection. Going through the generic type parameter is an unneeded indirection and hence not supported.

JaredPar
But what if you masked your static method in a child class?public class SomeChildClass : SomeBaseClass{ public new static StaticMethodOnSomeBaseClassThatReturnsCollection(){}}Could you do something to access that static method from a generic type?
Hugo Migneron
A: 

Here, i post an example that work, it's a workaround

public interface eInterface {
    void MethodOnSomeBaseClassThatReturnsCollection();
}

public T:SomeBaseClass, eInterface {

   public void MethodOnSomeBaseClassThatReturnsCollection() 
   { StaticMethodOnSomeBaseClassThatReturnsCollection() }

}

public Collection MethodThatFetchesSomething<T>() where T : SomeBaseClass, eInterface
{ 
   return ((eInterface)(new T()).StaticMethodOnSomeBaseClassThatReturnsCollection();
}