Domanda

Sto cercando di creare una libreria per semplificare le chiamate di binding in ritardo in C # e sto riscontrando problemi con i parametri di riferimento. Ho il seguente metodo per aggiungere un parametro utilizzato in una chiamata di metodo

    public IInvoker AddParameter(ref object value)
    {
        //List<object> _parameters = new List<object>();
        _parameters.Add(value);          

        //List<bool> _isRef = new List<bool>();
        _isRef.Add(true);

        return this;
    }

E questo non funziona con i tipi di valore, perché vengono inscatolati come un oggetto, quindi non vengono modificati. Per esempio:

int param1 = 2;
object paramObj = param1;
//MulFiveRef method multiplies the integer passed as a reference parameter by 5:
//void MulFiveRef(ref int value) { value *= 5; }
fi.Method("MulFiveRef").AddParameter(ref paramObj);

Non funziona. La chiamata di associazione tardiva ha esito positivo e l'elenco interno che contiene i parametri (_parameters) viene modificato, ma non il valore esterno alla chiamata.

Qualcuno conosce un modo semplice per superare questa limitazione? La firma AddParameter non può essere modificata, poiché con le chiamate di binding in ritardo, non è possibile conoscere in anticipo il Tipo di parametri (e in entrambi i casi si inseriscono tutti i parametri per una chiamata all'interno di un array di oggetti prima di effettuare la chiamata)

Grazie in anticipo.

È stato utile?

Soluzione

Se il valore sta cambiando all'interno del metodo , dovrai dichiarare una variabile temp ( oggetto ) da passare ( ref ) a il metodo e decomprimilo tu stesso in seguito:

    int i = 3;
    //...
    object obj = i;
    Foo(ref obj);
    i = (int)obj;

Nota che questo non ti permetterà di aggiornare il valore dopo l'evento. Qualcosa come un evento o una richiamata potrebbe essere un modo alternativo per restituire le modifiche al chiamante.

Nota anche che C # 4.0 ha alcuni trucchi per aiutare con questo solo nel contesto delle chiamate COM (dove ref object è così comune [più ovviamente dinamico per associazione tardiva, come osserva Jon]).

Altri suggerimenti

Il tuo metodo non sta modificando il valore - perché lo passi per riferimento? Può avere senso, ma non è molto chiaro per me. Tieni presente che il codice di esempio che hai fornito non verrà compilato comunque, poiché gli argomenti ref devono essere esattamente dello stesso tipo del parametro.

(Inoltre, sei consapevole che C # 4.0 e .NET 4.0 avranno il supporto integrato per il late-binding? È probabile che la versione integrata nella lingua sia più facile da usare rispetto a una sola libreria. vale la pena passare del tempo in biblioteca in questo momento?)

EDIT: il codice che hai fornito in realtà non verrà compilato. Non si ottiene la boxe per i parametri ref , proprio perché l'argomento e i tipi di parametro devono essere esattamente gli stessi. Ecco un po 'di codice di esempio per dimostrarlo:

public class Test
{
    static void Main()
    {
        int i;
        Foo(ref i); // Won't compile - error CS1502/1503
    }

    static void Foo(ref object x)
    {
    }
}

Se il tuo codice attuale è compilato, non è il codice che hai presentato nella domanda. Forse hai un altro sovraccarico per AddParameter che accetta ref int ?

Ok, grazie alle correzioni di Jon Skeet e al codice Mark Gravell, ho creato questa interfaccia:

        //This will be created with a factory
        IOperationInvoker invoker = new OperationInvoker(Activator.CreateInstance<MyLateBindingTestType>());

        int param1 = 2;
        object paramObj = param1;

        invoker.AddParameter(ref paramObj).Invoke("MulFiveRef");

        param1 = (int)invoker.Parameters[0];

Non è esattamente come l'ho immaginato, ma è molto più semplice e leggibile della mia interfaccia precedente:

        IOperationInvoker invoker = new OperationInvoker(Activator.CreateInstance<MyLateBindingTestType>());
        int refValue = 10;
        object[] args = Args.Build(refValue);

        invoker.Call("MulFiveRef", Args.ByRefIndexs(0), args);

        refValue = (int)args[0];

Grazie mille per l'aiuto persone :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top