Home > Software design >  Need to call a static factory method in a generic method (Error CS0119)
Need to call a static factory method in a generic method (Error CS0119)

Time:01-17

I need to call a static factory method from a generic method. Some solution suggest using reflection. Is there no other way to do so? Why C# has this constraint?

Here is my minimal example:

using System;

public class MainClass
{
    public static void Main(string[] args)
    {
        A a = Get<A>("apiA");
        B b = Get<B>("apiB");
    }
    
    public static T Get<T>(string url)
    {
        string json = "{}"; // answer received from api
        return T.Factory(json); // error CS0119: 'T' is a type parameter, which is not valid in the given context
    }
}

class A {
    // public field
    public static A Factory(string json)
    {
        // need to do more A-specific thing here
        return NotUnderMyControl.FromJson<A>(json);
    }
}

class B {
    // public fields
    public static B Factory(string json)
    {
        // need to do more B-specific thing here
        return NotUnderMyControl.FromJson<B>(json);
    }
}

static class NotUnderMyControl {
    public static T FromJson<T>(string json) where T : new()
    {
        return new T();
    }
}

CodePudding user response:

You may want to make the methods common in the interface and change static methods to instance methods.

public class MainClass
{
    public static void Main(string[] args)
    {
        A a = Get<A>("apiA");
        B b = Get<B>("apiB");
    }

    static class FactoryCache<T> where T : IFactory<T>, new()
    {
        public static readonly T Instance = new T();
    }

    public static T Get<T>(string url) where T : IFactory<T>, new()
    {
        string json = "{}"; // answer received from api

        return FactoryCache<T>.Instance.Factory(json);
    }
}

public interface IFactory<T>
{
    T Factory(string json);
}

class A : IFactory<A>
{
    public A Factory(string json)
    {
        return NotUnderMyControl.FromJson<A>(json);
    }
}

class B : IFactory<B>
{
    public B Factory(string json)    {
        return NotUnderMyControl.FromJson<B>(json);
    }
}
  • Related