1

Is it possible to make a call to static method from generic function?

I need to do something like this:

public static T CreateNewProject<T, V>(string token, string projectName)
     where V : IProject<T>
{
   V.LoadProject();
}

where LoadProject() MUST be some static method of some class.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
Ilan
  • 989
  • 2
  • 12
  • 22
  • No, you can't :-) Sadly interfaces can't define what static methods/constructors must be present. – xanatos Feb 24 '15 at 11:17
  • 1
    And see http://stackoverflow.com/questions/196661/calling-a-static-method-on-a-generic-type-parameter – xanatos Feb 24 '15 at 11:18
  • @xanatos So how can I make a call to static method? Can I use something instead of interface? – Ilan Feb 24 '15 at 11:19
  • (excuse me for closing as duplicate... while I DO think it's a duplicate (and even the proposed solution by Selman22 is suggested in one of the other questions), I didn't know I had the superpower of closing directly without other four persons reviewing it) – xanatos Feb 24 '15 at 11:26

2 Answers2

3

You can't do that with constraints, but you can use Reflection. It looks like the only choice in this case:

typeof(V).GetMethod("LoadProject", BindingFlags.Static | BindingFlags.Public)
         .Invoke(null);
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
2

What you could do is instead of using static classes is use a singleton:

public interface ICanLoadProject
{
    void LoadProject(string token, string projectName);
}

Implementation:

public class SampleProjectLoader : ICanLoadProject
{
    private static SampleProjectLoader instance = new SampleProjectLoader();

    private SampleProjectLoader(){} 

    public static SampleProjectLoader Instance { get{ return instance; } }

    public void LoadProject(string token, string projectName)
    { /*Your implementation*/ }

}

then the generic works with:

where V : ICanLoadProject

all you have to do with the code accessing the Method before is:

SampleProjectLoader.Instance.LoadProject("token","someName");

the method could be:

public static class ExtensionMethods
{
    public static T CreateNewProject<T, V>(this V loader, string token, string projectName) where V : ICanLoadProject
    {
        loader.LoadProject(token, projectName);
        return default(T); //no clue what you want to return here
    }
}

And will be called like:

static void Main(string[] args)
{
    object result = SampleProjectLoader.Instance.CreateNewProject<object, SampleProjectLoader>("token", "someName");
}

Or better yet:

public static class ExtensionMethods
{
    public static T CreateNewProject<T>(this ICanLoadProject loader, string token, string projectName)
    {
        loader.LoadProject(token, projectName);
        return default(T); //no clue what you want to return here
    }
}

and call with:

SampleProjectLoader.Instance.CreateNewProject<object>("token", "someName");
Florian Schmidinger
  • 4,682
  • 2
  • 16
  • 28
  • Very interesting solution, but I'd like to avoid passing an additional parameter "ICanLoadProject loader" to the "CreateNewProject" function. Is it possible? – Ilan Feb 24 '15 at 12:53
  • If you use an ExtensionMethod you dont.... you just call it on the instance like i did.... this will get the value of the instance you call it from... only downside is that it will have to be a static class where the method is implemented... you see the code i wrote... – Florian Schmidinger Feb 24 '15 at 12:58
  • Did I understand correct, I HAVE to pass "this V" or "this ICanLoadProject" as a parameter? I can't avoid this? – Ilan Feb 24 '15 at 13:02
  • and you could actually make another static method delegating the methodcall to LoadProject to instance.LoadProject in the ProjectLoader class... it just has to have a different name... – Florian Schmidinger Feb 24 '15 at 13:03
  • Nono i gave you examples of how to call it... use the last 2 implementations... then you only have one generic type to write – Florian Schmidinger Feb 24 '15 at 13:04
  • you dont write anything in loader ... you call the method on the instance and it gets assigned magically =) – Florian Schmidinger Feb 24 '15 at 13:04
  • you probably used ExtensionMethods like .Where() .Select() etc in linq – Florian Schmidinger Feb 24 '15 at 13:05
  • still not clear? ... parameters are (this ICanloadProject loader, string someother...) and this ICanLoadProject loader gets assinged to where you call the extension method from – Florian Schmidinger Feb 24 '15 at 13:07
  • I'm wondering is there a way NOT to pass any additional parameters to the CreateNewProject? Because if I would like to pass V param to the function I could do this in my original code above and then inside the function I could make a call like param.LoadProject() – Ilan Feb 24 '15 at 13:11
  • I fear im loosing you... you need to elaborate you mean the strings? – Florian Schmidinger Feb 24 '15 at 13:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/71584/discussion-between-ilan-and-florian-schmidinger). – Ilan Feb 24 '15 at 13:14