Передайте динамическую переменную в статическом параметре метода в C # 4 - PullRequest
2 голосов
/ 09 ноября 2011

Вот что я пытаюсь сделать:

public void method(int myVal, string myOtherVal)
{
  // doing something
}

dynamic myVar = new SomeDynamicObjectImplementer();
method(myVar.IntProperty, myVar.StringProperty);

Обратите внимание, что мои свойства также являются объектами DynamicObject.Моя проблема в том, что метод TryConvert никогда не вызывается, и я получаю сообщение об ошибке во время выполнения, в котором говорится, что подпись метода недействительна.

Следующее работает отлично:

string strVar = myVar.StringProperty;
int intVar = myVar.IntProperty;

И я хотел быизбежать

method((int)myVar.IntProperty, (string)myVar.StringProperty);

Можно ли что-то переопределить в DynamicObject, чтобы разрешить это?(или что-то еще)

Спасибо

Ответы [ 3 ]

2 голосов
/ 09 ноября 2011

Проблема в том, что вы предполагаете, что он попытается выполнить неявное динамическое преобразование аргументов динамического вызова, чтобы заставить вызов метода работать, это не так.

Когда ваши аргументы не являются статически типизированными, он будет использовать тип среды выполнения, чтобы найти наилучший подходящий метод (если тип среды выполнения соответствует статическим правилам для неявного преобразования в тип аргумента, это тоже будет работать), так как ваш IntProperty StringProperty, похоже, возвращает DynamicObject, а не Int и String или что-то, что может быть статически неявно преобразовано, этот поиск завершится неудачей.

Если бы SomeDynamicObjectImplementer мог на самом деле возвращать Int для IntProperty и String для StringProperty, вызов вашего метода без приведения будет фактически работать. Также, вероятно, лучше применять динамическую типизацию, если тип данных основан на фактическом типе данных, а не на использовании try convert. Вы можете добавить фактически неявные методы преобразования для каждого возможного типа, который вы можете вернуть к возвращенному типу DynamicObject, но это может вызвать странные проблемы с разрешением в зависимости от того, насколько вы перегружены.

Однако другой вариант, позволяющий сохранить динамическую реализацию такой же, - это смешать немного контролируемой статической типизации. Вы можете использовать ImpromputInterface (в nuget), чтобы поместить интерфейс поверх динамического объекта , если если вы сделаете это, то для ваших возвращенных объектов DynamicObjects будет вызван метод TryConvert.

public interface ISomeStaticInterface{
      int IntProperty {get;}
      string StringProperty {get;}
}
...
var myVar = new SomeDynamicObjectImplementer().ActLike<ISomeStaticInterface>();
method(myVar.IntProperty, myVar.StringProperty);
0 голосов
/ 09 ноября 2011

Зачем ты снимаешься?

метод (myVar.IntProperty, myVar.StringProperty);

должен скомпилироваться.

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

0 голосов
/ 09 ноября 2011

Вместо использования myVar.IntProperty вы не можете просто сначала поместить их в переменные, как вы уже сделали, а затем использовать для своего метода?

так что method(intVar , strVar); вроде нормально. По крайней мере, более элегантно, чем кастинг.

Конечно, если вы уже уверены, что ваш объект будет иметь IntProperty и StringProperty, почему бы просто не сделать реальный объект с этими свойствами вместо этого?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...