c # Аргумент равен 'ref', а параметр объявлен как 'значение' - PullRequest
0 голосов
/ 05 июля 2011
public virtual IAsyncResult BeginProcessRequest(RequestContext context, AsyncCallback callback, object state)
{
    return this.process.BeginInvoke(**ref context**, callback, state);
}

public virtual RequestContext EndProcessRequest(IAsyncResult result)
{
    RequestContext context = null;
    this.process.EndInvoke(**ref context**, result);
    return context;
}

Два вышеупомянутых метода вызывают некоторые предупреждения в моем проекте. Я не уверен, что понимаю их. Предупреждение:

Аргумент равен 'ref', а параметр объявлен как 'значение'

и местоположение предупреждения является первым параметром (контекстом) в вызовах Invoke. Кто-нибудь видит что-то не так с этим или у вас есть какой-то совет по этому вопросу?

Эти двойные звездочки являются причиной предупреждений. Я нажал «bold» в редакторе, и он сделал это, поэтому я просто пошел с этим. Звездочки не в моем коде.

Ответы [ 3 ]

7 голосов
/ 05 июля 2011

Использование ref с делегатами - плохая идея, ИМО.(Если честно, я бы сказал, что обычно это плохая идея. Заставьте ваши методы делать одно и иметь один результат.)

Я не думал, что это сработает вообще - но, очевидно, это сработает,до тех пор, пока вы предоставляете параметр ref при вызове EndInvoke:

using System;

class Program
{
    delegate void Foo(ref int x, string y);

    static void SampleFoo(ref int x, string y)
    {
        Console.WriteLine("Incoming: {0}", x); // 10
        x = y.Length;
    }

    static void Main(string[] args)
    {
        int x = 0;
        int input = 10;
        Foo f = SampleFoo;
        IAsyncResult result = f.BeginInvoke(ref input, "Hello", null, null);
        f.EndInvoke(ref x, result);
        Console.WriteLine("Result: {0}", x); // 5
    }
}

Поведение здесь потенциально сбивает с толку ... Я бы избегал его, если это вообще возможно.

Большинство случаев использования ref связано с непониманием того, как передача параметров работает в C # ... возможно ли, что это так?Вам действительно нужен первый параметр, который будет ref?Вы можете просто сделать возвращаемое значение делегата новым контекстом вместо этого?

5 голосов
/ 05 июля 2011

BeginInvoke вероятно не ожидает параметр ref там.Вы говорите ref context, то есть передаете ссылку на этот объект (ссылка сама по себе).Можете ли вы подтвердить подпись метода для BeginInvoke?

1 голос
/ 05 июля 2011

Я думаю, вы не совсем понимаете, как работает ref.

Прежде всего, ref (или out) является частью сигнатуры метода, поэтому, если в методе параметр обозначен как ref параметр, тогда вы должны использовать ref в противном случае вы не должны использовать ref

Во-вторых:

public virtual IAsyncResult BeginProcessRequest(RequestContext context, AsyncCallback callback, object state)
{
    return this.process.BeginInvoke(ref context, callback, state);
}

ref ничего не делает, потому что вы нигде не используете новое значение context. ref подобен out параметру, за исключением того, что он является одновременно "in" и "out". Нормальные параметры можно рассматривать только как «in» (я придумываю термин «in»).

...