Как я выражаю пустой вызов метода как результат DynamicMetaObject. BindInvokeMember?

Необходимо использовать isinstance

isinstance(...)
    isinstance(object, class-or-type-or-tuple) -> bool

    Return whether an object is an instance of a class or of a subclass thereof.
    With a type as second argument, return whether that is the object's type.
    The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for
    isinstance(x, A) or isinstance(x, B) or ... (etc.).
56
задан Jon Skeet 2 December 2009 в 21:22
поделиться

4 ответа

Это похоже на:

Тип возврата DLR

Вам необходимо сопоставить возвращаемый тип, указанный свойством ReturnType . Для всех стандартных двоичных файлов это фиксировано для объекта почти для всего или недействительно (для операций удаления). Если вы знаете, что делаете вызов void, я бы посоветовал обернуть его в:

Expression.Block(
    call,
    Expression.Default(typeof(object))
);

DLR был довольно небрежным в отношении того, что он допускал, и автоматически обеспечивал минимальное количество принуждения. Мы избавились от этого, потому что не хотели предоставлять набор условных обозначений, которые могли иметь или не иметь смысла для каждого языка.

Похоже, вы хотите предотвратить:

dynamic x = obj.SomeMember();

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

26
ответ дан 26 November 2019 в 17:31
поделиться

Мне это не нравится, но вроде работает; реальная проблема, похоже, заключается в том, что binder.ReturnType появляется странно (и не отбрасывается ("всплывает") автоматически), но:

if (target.Type != binder.ReturnType) {
    if (target.Type == typeof(void)) {
        target = Expression.Block(target, Expression.Default(binder.ReturnType));
    } else if (binder.ReturnType == typeof(void)) {
        target = Expression.Block(target, Expression.Empty());
    } else {
        target = Expression.Convert(target, binder.ReturnType);
    }
}
return new DynamicMetaObject(target, restrictions);
11
ответ дан 26 November 2019 в 17:31
поделиться

Возможно, call-сайт ожидает возврата null, но отбрасывает результат - Это перечисление выглядит интересно, особенно флаг «ResultDiscarded» ...

[Flags, EditorBrowsable(EditorBrowsableState.Never)]
public enum CSharpBinderFlags
{
    BinaryOperationLogical = 8,
    CheckedContext = 1,
    ConvertArrayIndex = 0x20,
    ConvertExplicit = 0x10,
    InvokeSimpleName = 2,
    InvokeSpecialName = 4,
    None = 0,
    ResultDiscarded = 0x100,
    ResultIndexed = 0x40,
    ValueFromCompoundAssignment = 0x80
}

Пища для размышлений ...

ОБНОВЛЕНИЕ :

Дополнительные подсказки можно почерпнуть из Microsoft / CSharp / RuntimeBinder / DynamicMetaObjectProviderDebugView, который используется (я полагаю) в качестве визуализатора для отладчиков. Метод TryEvalMethodVarArgs проверяет делегата и создает привязку с флагом отбрасывания результата (???)

 Type delegateType = Expression.GetDelegateType(list.ToArray());
    if (string.IsNullOrEmpty(name))
    {
        binder = new CSharpInvokeBinder(CSharpCallFlags.ResultDiscarded, AccessibilityContext, list2.ToArray());
    }
    else
    {
        binder = new CSharpInvokeMemberBinder(CSharpCallFlags.ResultDiscarded, name, AccessibilityContext, types, list2.ToArray());
    }
    CallSite site = CallSite.Create(delegateType, binder);

... Я нахожусь в конце моего Reflector-foo, но создание этого кода кажется немного странным, поскольку сам метод TryEvalMethodVarArgs ожидает объект в качестве возвращаемого типа, а последняя строка возвращает результат динамического вызова. Я, наверное, лаю не на то [выражение] дерево.

-Oisin

6
ответ дан 26 November 2019 в 17:31
поделиться

Связыватель C # (в Microsoft.CSharp.dll) знает, используется ли результат; как говорит x0n (+1), он отслеживает это во флаге. К сожалению, флаг скрыт внутри экземпляра CSharpInvokeMemberBinder , который является частным типом.

Похоже, что механизм привязки C # использует ICSharpInvokeOrInvokeMemberBinder.ResultDiscarded (свойство внутреннего интерфейса ) прочитать; CSharpInvokeMemberBinder реализует интерфейс (и свойство). Кажется, работа выполняется в Microsoft.CSharp.RuntimeBinder.BinderHelper.ConvertResult () . В этом методе есть код, который срабатывает, если вышеупомянутое свойство ResultDiscarded не возвращает истину, если тип выражения недействителен.

Так что мне не кажется, что там »

5
ответ дан 26 November 2019 в 17:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: