Как можно использовать динамический как универсальный?

Как я могу использовать динамический как универсальный?

это

<code>var x = something not strongly typed;
callFunction<x>();
</code>

и это

<code>dynamic x = something not strongly typed;
callFunction<x>();
</code>

оба выдают эту ошибку

<code>Error   1   The type or namespace name 'x' 
could not be found (are you missing a using directive or an assembly reference?)
</code>

Что я могу сделать, чтобыx сделать его достаточно законным для использования в<x>?

 Travis J13 апр. 2012 г., 00:28
@ M.Babcock - даже при преобразовании в тип выдается та же ошибка. Например:Type t; t = LegitimateObject.GetType(); callFunction<t>(); выдает ту же ошибку.
 M.Babcock13 апр. 2012 г., 00:26
Ваш код сбивает с толку. Похоже, вы пытаетесь передать переменную в качестве параметра типа? Это все равно не сработает. Это должен быть тип.
 M.Babcock13 апр. 2012 г., 00:29
Нет не тип, как вSystem.Type тип как вstring или жеint непосредственно. Переменные нельзя использовать в качестве параметров типа.
 Olivier Jacot-Descombes13 апр. 2012 г., 00:32
var x не означает, что переменнаяx не сильно напечатан. Компилятор выводит (угадывает, если вы предпочитаете) тип выражения справа от= и делает это типомx, Если компилятор считает, что выражение имеет типstring затемvar x означает точно так же, какstring x, Обратите внимание, что это происходит во время компиляции, а не во время выполнения!
 phoog13 апр. 2012 г., 00:49
Ваш пример кода не имеет смысла: рассмотрите ваш код, если xwere строго напечатано:string x = "X";, Вы не звонитеCallFunction<x>() или жеCallFunction<typeof(string)>(); ты звонишьCallFunction<string>()  Это не имеет смысла, если только CallFunction не имеет строкового параметра или возвращаемого значения; Более вероятный звонок будетstring x = CallFunction<string>(); или жеCallFunction<string>(x), Можете ли вы привести пример функции, которую вы хотели бы вызвать? Чего ты пытаешься достичь?

Ответы на вопрос(6)

Трудно сказать, что именно вы пытаетесь сделать. Но если вы хотите вызвать универсальный метод с параметром типа, который совпадает с некоторым объектом, вы не можете сделать это напрямую. Но вы можете написать другой метод, который принимает ваш объект в качестве параметра,dynamic выведите тип и затем вызовите нужный метод:

void HelperMethod<T>(T obj)
{
    CallFunction<T>();
}

…

dynamic x = …;
HelperMethod(x);
 16 янв. 2014 г., 16:07
Ничего себе .. это потрясающе .. Тонкая разница в том, что когдаx имеет значение null, механизм вывода типов здесь не работает. Еслиx строго типизирован, сам вызов метода не потерпит неудачу. Просто что-то иметь в виду ..

Вы должны быть в состоянии вызвать функцию, как это

callFunction<dynamic>();

Если ваша функция определяется как

public void callFunction<T>(T arg) {
    ...
}

Вы можете просто позвонить с

callFunction(x);

C # может выводить параметры универсального типа во многих ситуациях.

Решение Вопроса

Вы можете использовать вывод типа для батута вызова:

dynamic x = something not strongly typed;
CallFunctionWithInference(x);

...

static void CallFunctionWithInference<T>(T ignored)
{
    CallFunction<T>();
}

static void CallFunction<T>()
{
    // This is the method we really wanted to call
}

Это определит аргумент типа во время выполнения на основе типа времени выполнения значенияxиспользуя тот же тип вывода типа, который он использовал бы, еслиx было это как егоcompile-time тип. Параметрonly подарок, чтобы сделать вывод типа работы.

Обратите внимание, что в отличие от Дарина, я верю в этоis полезный метод - в тех же самых ситуациях, когда перед динамикой вы в конечном итоге вызываете универсальный метод с отражением. Вы можете сделать этоone часть кода динамическая, но сохранитьrest кода (от общего типа и далее) безопасного типа. Это позволяетone шаг, чтобы быть динамичным - только один бит, когда вы не знаете тип.

 13 апр. 2012 г., 00:47
@TravisJ: Это потому чтоCallFunction само по себе имеет ограничение? Вы не сказали нам, что в вопросе :) Без ограничения наCallFunction это должно быть хорошо, хотя.
 Travis J13 апр. 2012 г., 00:45
Хах! Это работает, хорошо с небольшой адаптацией. Чистый гений. Я люблю это. Проблема в том, что с вашим текущим определением T должен быть ссылочным типом, чтобы использовать его в качестве параметра позже вCallFunction, Чтобы улучшить это, я сделал эти изменения:static void CallFunctionWithInference<T>(T ignored) where T : class а такжеstatic void CallFunctionWithInference<T>(T ignored) where T : class, Еще раз спасибо! Я хотел бы иметь больше, чем +1.
 23 авг. 2012 г., 18:33
@TravisJ: Я думаю, что было бы полезно, если бы вы могли создать новый вопрос для этого, с коротким, ноcomplete Программа, демонстрирующая проблему.
 Travis J13 апр. 2012 г., 00:49
Да, извините за упущение :) Ограничение вCallFunction является инициализацией (вниз по линии) EF DbSet в видеthis.dbSet = context.Set<TEntity>(); который находится внутри общего репозитория, вызываемого из оператора using. В то время я не понимал, что это повлияет на результат, иначе я бы включил его.
 03 мая 2012 г., 07:30
@TravisJ: Очень любезно с вашей стороны - спасибо!

Самый быстрый способ сделать эту работу - сделать ваш анонимный тип настоящим типом.

Так что вместо

var x = new { Value = "somevalue", Text = "sometext" };

Вам нужно сделать

class MyClass
{
    string Text, Value;
}
....
var x = new MyClass() { Value = "somevalue", Text = "sometext" };
//this should work now
callFunction<MyClass>(x);
 13 апр. 2012 г., 00:38
Обратите внимание, чтоx все еще строго напечатан в первом фрагменте кода; однако тип является анонимным.

Вы не можете ". Весь смысл обобщений заключается в безопасности во время компиляции, что означает, что они должны быть известны во время компиляции. И все дело в том, что вам не нужно знать точный тип во время компиляции и использовать диспетчерскую диспетчеризацию = & gt; это абсолютно точная противоположность дженериков. Так что не тратьте свое время = & gt; как только вы получите динамический путь / путь отражения, вы можете забыть об обобщениях и безопасности во время компиляции. Вам придется идти по этому пути до конца.

Итак, чтобы ответить на ваш вопрос:

What can I do to x to make it legitimate enough to be used in ?

Единственное, что вы можете сделать, это использовать тип, который известен во время компиляции, иначе вы не сможете использовать обобщенные типы.

 13 апр. 2012 г., 00:36
Ну, вы можете использовать дженерики с типом, который не известен во время компиляции, см. Мой ответ.

Вы получаете эту ошибку, потому чтоx это не тип. Вам нужно указать тип какtype параметр.

На самом деле, выcan использованиеdynamic в качестве параметра типа, если вы используете его правильно:

var dict = new Dictionary<string, dynamic>();

dict.Add("Item1", 123);
dict.Add("Item2", "Blah");

Это компилируется и работает просто отлично.

Ваш ответ на вопрос