Невозможно предоставить аргументы при создании экземпляра родового типа
У меня есть объект, который я хочу читать только после его создания... а именно потому, что свойства в конструкторе должны использоваться в 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
Каков наилучший способ обойти эту ситуацию?
-
Должен ли я иметь интерфейс, который я могу вызвать, который обновит свойство?
-
Будет ли предыдущий интерфейс обрывать инкапсуляцию или разрешить внесение изменений в мой объект?
-
Как еще я должен подходить к этому?
Ответы
Ответ 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
.