Question

Considérez:

object o = 123456U;
ulong l = (ulong) o; // fails

Mais ceci:

object o = 123456U;
ulong l = (ulong) (uint) o; // succeeds

La vraie question que j'ai est que je voudrais avoir une fonction en fonction d'un type de paramètre, les traite différemment. Tels que:

void foo(object o)
{
switch (Type.GetTypeCode(o.GetType()))
   {
      case TypeCode.UInt32:
      case TypeCode.UInt64:
      ulong l = (ulong) o;
      RunUnsignedIntVersion(l);
      break;
      case TypeCode.Int32:
      case TypeCode.Int64:
      long n = (long) o;
      RunSignedVersion(n);
      break;
   }
}

et vous ne pouvez pas faire les appels suivants:

foo(123456U);
foo(123456);

Je sais qu'il ya des façons de le faire en utilisant les médicaments génériques. Mais j'utilise le cadre de micro .net et génériques ne sont pas pris en charge. Mais les caractéristiques spécifiques C # 3.0 du compilateur sont pris en charge, y compris les fonctions anonymes.

Modifier Je voudrais éviter d'avoir à gérer chaque type séparément. Est-il possible, cela peut être fait et ont encore un paramètre de type d'objet?

Était-ce utile?

La solution

Les opérations de Unbox ne supportent que les Unbox, aucune contrainte que vous pourriez attendre.

Alors que cela peut être frustrant, il est intéressant de noter que la fixation cela

  1. unboxing beaucoup plus cher
  2. compliquerait peut-être la langue en raison de cas de pointe désagréables sur la sélection de surcharge de la méthode

, entre autres, pour une explication approfondie, Eric Lippert est, comme toujours, plus instructif

Si vous vous souciez de la performance le seul moyen efficace de le faire est (comme le souligne Jimmy out)

case TypeCode.Int32:
    RunSignedVersion((int) o);
    break;
case TypeCode.Int64:
    long n = (long) o;
    RunSignedVersion(n);
    break;

Cela ne semble pas trop onéreux.

Si cela est trop douloureux, vous pouvez utiliser Convert.ToInt64 ou Convert.ToUInt64 () avec le coût associé.

void foo(object o)
{
   switch (Type.GetTypeCode(o.GetType()))
   {
      case TypeCode.UInt32:
      case TypeCode.UInt64:
          ulong l = Convert.ToUInt64(o);
          RunUnsignedIntVersion(l);
          break;
      case TypeCode.Int32:
      case TypeCode.Int64:
          long n = Convert.ToInt64(o);
          RunSignedVersion(n);
          break;
   }
}

Si Convert est pas disponible est ici la source de rotor pour les méthodes pertinentes:

    [CLSCompliant(false)]   
    public static ulong ToUInt64(object value) {
        return value == null? 0: ((IConvertible)value).ToUInt64(null);
    }

    [CLSCompliant(false)]   
    public static long ToInt64(object value) {
        return value == null? 0: ((IConvertible)value).ToInt64(null);
    }

IConvertible est pris en charge comme une interface dans le cadre compact, je suppose que ce serait donc travailler mais n'a pas essayé.

Si vous voulez MicroFramework alors je suggère simplement la mise en œuvre des options de conversion sur une base par type est le meilleur que vous pouvez faire. L'API est si rares qu'il n'y a vraiment pas grand-chose possible . Je dirais aussi que tout basé sur la boxe est risqué car il est une allocation importante surcharge dans une très mémoire environnement contraint.

Si vous essayez de mettre en œuvre un string.Format () avez-vous pensé aussi bien System.Ext.Text.StringBuilder.AppendFormat suivi d'un ToString?

Autres conseils

  case TypeCode.Int32:
    RunSignedVersion((int) o);
    break;
  case TypeCode.Int64:
    long n = (long) o;
    RunSignedVersion(n);
    break;

la raison pour laquelle vous ne pouvez pas Unbox comme int est parce que unboxing et la coulée sont deux opérations différentes qui arrivent à partager le même opérateur.

Ceci est parce que vous pouvez seulement Unbox au même type qui a été à l'origine en boîte (ou à la version annulable de ce type).

Par exemple, un byte en boîte ne peut être Unboxed à byte ou byte?, un int en boîte ne peut être Unboxed à int ou int?, un long boxed ne peut être Unboxed à long ou long? etc etc.

Vous pouvez créer une méthode d'extension comme ça:

public static class ConversionExtensions
{
    public static ulong ToUInt64(this object value)
    {
        return ((IConvertible)value).ToUInt64();
    }
}

Vous pouvez alors l'utiliser comme suit:

object o = 123456U;
ulong l = o.ToUInt64();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top