Why can't a base access expression be dynamically dispatched in C#?

return убивает выполнение функции и возвращает значение.

public function store(Request $request)
    {
        //
        $this->validate($request,[
            'product_name' => 'required|string|max:191',
            'quantity' => 'required|integer',
            'product_id' => 'required',
            'category' => 'string|max:191',
            'brand' => 'string|max:191',
            'provider_id' => 'required'
        ]);

        $product = Product::create([
            'product_name' => $request['product_name'],
            'quantity' => $request['quantity']
        ]); 

        $productDetails = ProductDetails::create([
            'product_id' => $request['product_id'],
            'category' => $request['category'],
            'brand' => $request['brand'],
            'provider_id' => $request['provider_id']
        ]);

        return $product;

    }
24
задан Ola Herrdahl 10 August 2010 в 20:56
поделиться

4 ответа

Да, это не может работать по замыслу. Вызов base.MethodA () выполняет невиртуальный вызов виртуального метода. У компилятора нет проблем с выдачей IL для этого в нединамическом случае, поскольку он знает, какой конкретный метод нужно вызвать.

Это не относится к динамической отправке. Задача DLR - выяснить, какой именно метод нужно вызвать. Он должен работать с таблицей методов производного класса. Эта таблица не содержит адрес метода MethodA базового класса. Он был перезаписан переопределением. Все, что он может сделать, это вызвать метод Derived.MethodA (). Что нарушает договор о базовом ключевом слове.

20
ответ дан 29 November 2019 в 00:10
поделиться

В вашем примере, Derived не имеет метода с именем MethodA, поэтому вызов base.MethodA() аналогичен вызову this.MethodA(), поэтому вы можете просто вызвать метод напрямую и покончить с ним. Но я предполагаю, что у вас есть другой this.MethodA(), и вы хотите иметь возможность звонить base.MethodA(). В этом случае просто послушайте совет компилятора и приведите аргумент к object (помните, что dynamic действительно просто object, что компилятор обрабатывает особым образом):

base.MethodA((object)input);
10
ответ дан 29 November 2019 в 00:10
поделиться

Проблема заключается не в динамическом аргументе, а в том, что вызов использует DLR для диспетчеризации (что показано в следующем примере). Возможно, такой вызов не поддерживается DLR.

public class Base
{
    public virtual void Method(int input)
    {
    }
}

public class Super : Base
{
    public override void Method(int input)
    {
        dynamic x = input;
        base.Method(x); // invalid
    }
}
-1
ответ дан 29 November 2019 в 00:10
поделиться

Вы можете использовать это:

((Base)this).MethodA(input);

В спецификации сказано:

Во время привязки, базовый доступ выражения формы base.I и base [E] оцениваются точно так же, как если бы они были написаны ((B) это) .I и ((B) this) [E], где B - база класс класса или структуры, в которой возникает конструкция

Итак, почему ваш пример дает ошибку и эта конструкция компилируется хорошо, это хороший вопрос.

-2
ответ дан 29 November 2019 в 00:10
поделиться
Другие вопросы по тегам:

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