2009-09-14 7 views
0

Je voudrais avoir une méthode où le paramètre pourrait être Int32 ou Single:C# passage simple comme référence

void myMethod(ref object x) 
{ 
    //...CodeHere 
} 

Depuis C# ne me permet pas de passer une spécialisation de l'objet lors de l'utilisation out ou ref, la solution que je trouve a affirmé que l'attribution de la variable à une variable du type object serait suffisant:

Single s = 1.0F; 
object o = s; 
myMethod(ref o); 

cela n'a pas fonctionné. Selon la documentation de Microsoft que j'ai regardé, o devrait être un pointeur vers s. Les sources que j'ai regardées indiquent que l'attribution de types non-primitifs génère une référence et non une instance new.

Est-il possible d'avoir une méthode où je peux passer Single ou Int32 ou tout autre type qui est une spécialisation de object?

+1

vous avez mal lu tous les documents en boxe que vous aviez en face de vous. Il a généré une instance encadrée à une copie de la valeur d'origine. –

Répondre

9

surcharge la méthode:

void myMethod(ref int x) 
{ 
    //... 
} 

void myMethod(ref single x) 
{ 
    //... 
} 
+0

Ma première solution à ce problème était exactement cela, mais je pensais que cela devrait être une autre façon. Ce problème semble être spécifique avec Single et connexes. Les classes complexes ne souffrent pas de cette limitation. De toute façon, si aucune autre solution n'apparaît, je vais utiliser votre suggestion. merci –

+0

Flavio: la raison pour laquelle cela ne fonctionne pas comme vous le pensez, c'est le fait que les ints et les floats sont des types de valeur, tandis que object est un type de référence. Je vous suggère de lire la différence. Voici un bon début (http://www.albahari.com/valuevsreftypes.aspx), mais je vous suggère de passer une heure ou deux sur le sujet. – Randolpho

1

Malheureusement, vous êtes hors de la chance. Vous serez mieux en utilisant deux méthodes:

void MyMethod(ref float x) 
{ 
    //.... 
} 

void MyMethod(ref int x) 
{ 
    //.... 
} 
+0

vous étiez le premier :) –

+0

En fait, Joel m'a battu de 3 secondes. :) – Randolpho

1

« Je voudrais avoir une méthode où le paramètre pourrait être Int32 ou simple »

Que diriez-vous à l'aide d'un Generic method à la place? NB: Dans la version actuelle de C#, vous ne pouvez contraindre que les types autorisés à structurer des types non spécifiques tels que int, float.

+2

Vous ne pouvez pas contraindre le paramètre générique à être seulement 'int' ou' float'. Le plus proche que vous pourriez obtenir serait de le restreindre à 'struct', ce qui permettrait à beaucoup d'autres types de se glisser. – LukeH

+0

Oui, c'est vrai, ai-je entendu des rumeurs que cela arrive en C# 4. – Ash

0

au lieu de la boxe la valeur dans un objet, vous pouvez surcharger la fonction:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
     } 

     static int test = 0; 

     static void MyMethod(int arg) 
     { 
      test += arg; 
     } 

     static void MyMethod(ref int arg) 
     { 
      test += arg; 
     } 

     static void MyMethod(Single arg) 
     { 
      test += Convert.ToInt32(arg); 
     } 

     static void MyMethod(ref Single arg) 
     { 
      test += Convert.ToInt32(arg); 
     } 
    } 
} 

Ce que vous faites avec l'argument à l'intérieur des méthodes dépend de ce que vous essayez d'accomplir, bien sûr.

0

Je probablement utiliser l'approche de Ash et aller avec une implémentation générique le long des lignes suivantes:

static void myMethod<T>(ref T value) where T : struct, IConvertible, IComparable<T>, IEquatable<T> 
    { 
     value = (T)Convert.ChangeType(value.ToSingle(CultureInfo.CurrentCulture) * 2.0, typeof(T)); 
    } 

    static void Main(string[] args) 
    { 
     int data1 = 5; 

     myMethod(ref data1); 
     if (data1 != 10) 
      throw new InvalidOperationException(); 

     Single data2 = 1.5f; 

     myMethod(ref data2); 
     if (data2 != 3) 
      throw new InvalidOperationException(); 
    }