Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot provide arguments when creating an instance of generic type

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?

like image 505
makerofthings7 Avatar asked Dec 16 '12 20:12

makerofthings7


People also ask

Can you create instances of generic type parameters?

A generic type is like a template. You cannot create instances of it unless you specify real types for its generic type parameters. To do this at run time, using reflection, requires the MakeGenericType method.

Can you create an instance of generic interface?

In similar way, we can create generic interfaces in java. We can also have multiple type parameters as in Map interface. Again we can provide parameterized value to a parameterized type also, for example new HashMap<String, List<String>>(); is valid.

Can constructor be generic in C#?

To call the Lesson class with the concrete type, you will need to initialize the object with the tags < > , and inside it you should specify the concrete type you want to create your Lesson class with. Can we have a generic constructor? No, generic constructors are not allowed.

What is generic in C# with example?

Generic Class T is called type parameter, which can be used as a type of fields, properties, method parameters, return types, and delegates in the DataStore class. For example, Data is generic property because we have used a type parameter T as its type instead of the specific data type.


1 Answers

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.

like image 181
Sergey Kalinichenko Avatar answered Oct 22 '22 21:10

Sergey Kalinichenko