Подтвердить что ты не робот

Невозможно предоставить аргументы при создании экземпляра родового типа

У меня есть объект, который я хочу читать только после его создания... а именно потому, что свойства в конструкторе должны использоваться в GetHashCode и, следовательно, не могут быть изменены после создания.

Я это один из многих классов, которые только для чтения:

public class AccountLabel
{ 
    private string result;

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

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

У меня есть общий класс результатов, подобный этому

  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
    }

Моя проблема в том, что я хочу передать объект в конструктор T, но не могу. Когда я набираю это, компилятор сообщает мне Cannot provide arguments when creating an instance of variable type

Каков наилучший способ обойти эту ситуацию?

  • Должен ли я иметь интерфейс, который я могу вызвать, который обновит свойство?

  • Будет ли предыдущий интерфейс обрывать инкапсуляцию или разрешить внесение изменений в мой объект?

  • Как еще я должен подходить к этому?

4b9b3361

Ответ 1

Вы можете удалить ограничение типа new и вместо этого использовать Activator.CreateInstance.

Вместо этого

T someResult = new T(tempresult);

напишите это:

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

Это, вероятно, будет несколько медленнее из-за прохождения рефлексии, и статические проверки компилятором не будут выполняться. Однако, учитывая ваш сценарий, похоже, что ни одна из этих проблем не представляет серьезной проблемы в вашем сценарии.

Ответ 2

Вы можете передать делегату factory конструктору JSonResult<T>:

public class JsonResult<T> where T : JObject
{
    public JsonResult(Newtonsoft.Json.Linq.JObject ret, Func<object, T> factory)
    { 
        var tempresult = ret["result"];
        T someResult = factory(tempresult);
    }
}

object в Func<object, T> можно заменить любым типом tempResult.