Cannot provide arguments when creating an instance of generic type

halfbit picture halfbit · Dec 16, 2012 · Viewed 7.1k times · Source

I have an object that I want to have read only after it is created... namely because the properties in the constructor must be used in GetHashCode, and therefore can't change once created.

I this is one of many classes that are readonly:

public class AccountLabel
{ 
    private string result;

    public AccountLabel(string result)
    {
        // TODO: Complete member initialization
        this.result = result;
    }

    public string JSONRPCData { get { return this.result; } }
}

I have a generic result class like this

  public  class JsonResult<T>  where  T : JObject, new()
  {
    private T bhash;
    private string p;
    private JsonErrorResponse error;
    private int _id;
    private Newtonsoft.Json.Linq.JObject ret;

    public JsonResult(Newtonsoft.Json.Linq.JObject ret)
    { 
        this.ret = ret;

        var tempError = ret["error"];
        var tempid = ret["id"];
        JsonErrorResponse error = new JsonErrorResponse(tempError);
        this.error = error;
        this._id = 1;


        var tempresult = ret["result"];
        T someResult = new T(tempresult);  // <--- here is my problem
    }

My problem is that I want to pass an object into T's constructor but can't. When I type this the compiler tells me Cannot provide arguments when creating an instance of variable type

What is the best way to work around this situation?

  • Should I have an Interface that I can call that will update the property?

  • Will that previous Interface break encapsulation or allow changes to be made to my object?

  • How else should I approach this?

Answer

Sergey Kalinichenko picture Sergey Kalinichenko · Dec 16, 2012

You can remove the new type constraint, and use Activator.CreateInstance instead.

Instead of this

T someResult = new T(tempresult);

write this:

T someResult = (T)Activator.CreateInstance(
    typeof(T)
,   new object[] { tempresult }
);

This is likely to be somewhat slower because of going through reflection, and the static checks by the compiler would not be performed. However, considering your scenario, it does not look like either of these would present a significant problem.