Gabriel J Gabriel J - 1 year ago 62
C# Question

Call static method from generic abstract class without specifying a type

I have an abstract class like this:

public abstract class BaseCamera<TCamera> : ICamera where TCamera : ManagedCameraBase
{
public static uint GetNumberOfCameras()
{
using (var bus = new ManagedBusManager())
{
bus.RescanBus();
return bus.GetNumOfCameras();
}
}
}


And want to call it like this:
BaseCamera.GetNumberOfCameras()


It makes sense to me, because since this is an abstract class, only the concrete children classes must choose a
TCamera
, and the base class wants to get the number of all cameras, no matter they type.

However, the compiler does not approve:


Using the Generic type 'BaseCamera' requires 1 type
arguments.


Is there some way around it or do I need to create a new class just for this?

I think it is worth pointing out that
ManagedCameraBase
is a class from an external API I'm wrapping. Therefore, I do not want to include it in any of my calls for
BaseCamera
and that is why I'm trying to avoid specifying a type.

Answer Source

Here's the problem. The static method GetNumberOfCameras belongs to the class that contains it, but a generic class actually gets compiled into separate classes for each type. So, for example if you had this:

public class Foo<T>
{
    static int foo = 0;

    public static void IncrementFoo()
    {
        foo++;
    }

    public static int GetFoo()
    {
        return foo;
    }
}

And then you did this:

Foo<string>.IncrementFoo();
Console.WriteLine(Foo<string>.GetFoo());
Console.WriteLine(Foo<int>.GetFoo());

You will see that the first call to GetFoo will return one, but the second will return zero. Foo<string>.GetFoo() and Foo<int>.GetFoo() are two separate static method that belong to two different classes (and access two different fields). So that's why you need a type. Otherwise the compiler won't know which static method of which class to call.

What you need is a non-generic base class for your generic class to inherit from. So if you do this:

public class Foo<T> : Foo
{

}

public class Foo
{
    static int foo = 0;

    public static void IncrementFoo()
    {
        foo++;
    }

    public static int GetFoo()
    {
        return foo;
    }
}

Then this:

Foo<string>.IncrementFoo();
Console.WriteLine(Foo<string>.GetFoo());
Console.WriteLine(Foo<int>.GetFoo());

Will give you what you might have expected at first. In other words, both calls to GetFoo will return the same result. And, of course, you don't actually need the type argument anymore and can just do:

Foo.IncrementFoo();

Or course, the alternative is to just move your static methods into an entirely different class if there's no reason why it should be part of BaseCamera

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download