views:

2762

answers:

7

Is there a simple way to implement this, and if possible without instanciating an object :

interface I
{
     static  string GetClassName();
}

public class Helper
{

    static void PrintClassName<T>() where T : I
    {
         Console.WriteLine(T.GetClassName());
    }
}
+1  A: 

I also tried to setup a static method on an interface a little while ago, not sure why now. I did bookmark this so maybe it helps:

Interface with a static method by using extension methods

Nick Clarke
+6  A: 

You can not inherit static methods. Your code wouldn't compile in any way, because a interface can't have static methods because of this.

As quoted from littleguru:

Inheritance in .NET works only on instance base. Static methods are defined on the type level not on the instance level. That is why overriding doesn't work with static methods/properties/events...

Static methods are only held once in memory. There is no virtual table etc. that is created for them.

If you invoke an instance method in .NET, you always give it the current instance. This is hidden by the .NET runtime, but it happens. Each instance method has as first argument a pointer (reference) to the object that the method is run on. This doesn't happen with static methods (as they are defined on type level). How should the compiler decide to select the method to invoke?

Dykam
For sure the compiler can't choose (or if he can that because we explicitly call the right static focntion with the right class). However can we do no have something around this with genereic ?
Toto
Probably it could be possible. But this design is chosen to keep it more simple and clean.
Dykam
+7  A: 

Try an extension method instead:

public interface IMyInterface
{
     string GetClassName();
}

public static class IMyInterfaceExtentions
{
    public static void PrintClassName<T>( this T input ) 
        where T : IMyInterface
    {
         Console.WriteLine(input.GetClassName());
    }
}

This allows you to add static extension/utility method, but you still need an instance of your IMyInterface implementation.

You can't have interfaces for static methods because it wouldn't make sense, they're utility methods without an instance and hence they don't really have a type.

Keith
Ok, but do you think we can avoid the input parameter. Say we have a kind of singleton pattern for the interface or in any other way?
Toto
Note sure what you mean - you'd call this extension methods as if it was an instance one: new MyImplementation().PrintClassName()
Keith
You can't avoid the instance, unless you switch to using reflection (like @Kent Boogaart's answer), but then you shouldn't really use generics as you're just passing the type
Keith
+3  A: 

If you're just after the type name, you can just do this:

public class Helper
{
    static void PrintClassName<T>()
    {
         Console.WriteLine(typeof(T).Name);
    }
}

HTH, Kent

Kent Boogaart
Nice answer (+1) but I'd add that you shouldn't really do this - if all you're doing is passing a type you should use a regular parameter instead: PrintClassName( Type input ) { Console.WriteLine(input.Name); }
Keith
+1  A: 

The answer is a qualified "not really but Sort Of". You can provide a static extension method to all implementors of a given interface and can then call this from your implementer in a property or another method. As an example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace InterfacesWithGenerics
{
    class Program
    {
     static void Main(string[] args)
     {
      Helper.PrintClassName<Example>(new Example());
      Console.ReadLine();
     }
    }

    public class Example : I
    {
     #region I Members

     public string ClassName
     {
      get { return this.GetClassName(); }
     }

     #endregion
    }

    public interface I
    {
     string ClassName { get; }
    }

    public class Helper
    {

     public static void PrintClassName<T>(T input) where T : I
     {   
      Console.WriteLine( input.GetClassName()) ;
     }
    }

    public static class IExtensions
    {
     public static string GetClassName(this I yourInterface)
     {
      return yourInterface.GetType().ToString();
     }
    }
}

Here we have an interface (I) which defines the property we care about and a static extension method (GetClassName) which is applied to all members of its type which does the grunt work of getting the information we want. We Have a Class (Example) which implements the I interface so when we call our static helper class passing in an instance of Example, it runs the static method against it. Unfortunately it is not valid to reference the type T directly within the method itself as a variable, you'll have to pass an instance into the application.

Wolfwyrd
A: 

Declaring a static property, event or method on an interface definition is not considered a legal definition. This is because interfaces are considered contracts and as such, represent something that will be implemented by every client instance of that interface.

A static declaration essentially states that the static member does not require a physical client implementation in order to execute the required functionality and this falls short of the general concept of interfaces: providing a proven contract.

Mike J
A: 

You could define the className as attribute on the specific class. This is the preferred ay to store metadata in .net. This way you can query the attribute for the given class and you do not need an instance.

codymanix