views:

337

answers:

5

All I want to do is make sure that child classes of the class Item implement a static method and I want this to be checked at compile time to avoid runtime errors.

abstract classes with static methods don't seem to work:

ERROR: A static member cannot be marked as override, virtual, or abstract

public abstract class Item
{
    public static abstract Item GetHistoricalItem(int id, DateTime pastDateTime);
}

public class Customer : Item
{
    public static override Customer GetHistoricalItem(int id, DateTime pastDateTime)
    {
        return new Customer();
    }
}

public class Address : Item
{
    public static override Address GetHistoricalItem(int id, DateTime pastDateTime)
    {
        return new Address();
    }
}

and interfaces don't seem to work either:

ERROR: Customer does not implement interface member GetHistoricalItem()

public class Customer : Item, HistoricalItem
{
    public static Customer GetHistoricalItem(int id, DateTime pastDateTime)
    {
        return new Customer();
    }
}

public class Address : Item, HistoricalItem
{
    public static Address GetHistoricalItem(int id, DateTime pastDateTime)
    {
        return new Address();
    }
}

interface HistoricalItem
{
    Item GetHistoricalItem();
}

Is there some workaround for this to have the compiler check if inheriting classes implement a static method with a certain signature or not?

+1  A: 

By definition a static method cannot be implemented in derived classes.

Darin Dimitrov
+1  A: 

Seems it's not possible, take a look: Is there a way to force a C# class to implement certain static functions?

Rubens Farias
+2  A: 

This cannout be done.

Have a look at Why can’t I have abstract static methods in c#?

astander
+2  A: 

It doesn't make sense to force clients to implement a static method - static methods are "immutable." (There's probably a better way to describe them but that's all my mind can come up with right now!)

If some sort of overriding is required, I would consider re-visiting the design, possibly using some form of a combination of singletons and injection?

What is it that you're trying to achieve?

Rich
I have an class Item which various objects inherit, e.g. Customer, Address, etc. And if a class is of type Item, then I want to be able to call a factory method on it called GetHistoricalItem(). So I want to be able to say Address address = Address.GetHistoricalItem(...). And I want to know at compile time that all my classes which inherit Item do this. It should just work the same way it does for instance methods.
Edward Tanguay
+4  A: 

There is a workaround i figured out for your scenario:

public class Customer : Reference<Customer>, IHistoricalItem
{
}

public class Address : Reference<Address>, IHistoricalItem
{
}

public interface IHistoricalItem
{
}

public class Reference<T> where T : IHistoricalItem, new()
{
    public static T GetHistoricItem(int id, DateTime pastDateTime)
    {
        return new T();
    }
}

Hope this helps!!

viky
+1 That's the way to solve OP's problem.
Groo