2009-07-30 7 views
27

J'ai un objet:Comment convertir un objet en type décrit par Type classe?

ExampleClass ex = new ExampleClass(); 

Et:

Type TargetType 

je voudrais jeter ex au type décrit par TargetType comme ceci:

Object o = (TargetType) ex; 

Mais quand je fais cela, je obtenir:

Le type ou nom d'espace de nommage 't' pourrait pas trouvé

Alors, comment faire? Ai-je manqué quelque chose d'obèle ici?

Mise à jour:

Je voudrais obtenir quelque chose comme ceci:

public CustomClass MyClassOuter 
{ 
    get 
    { 
     return (CustomClass) otherClass; 
    } 
} 

private otherClass; 

Et parce que je vais avoir de nombreuses propriétés comme cela, je voudrais faire:

public CustomClass MyClassOuter 
{ 
    get 
    { 
     return (GetThisPropertyType()) otherClass; 
    } 
} 

private SomeOtherTypeClass otherClass; 

Contexte:

Normalement dans mon contexte dans ma classe je dois créer beaucoup de propriété s. Et dans chacun remplacer le moulage au type de propriété. Cela ne semble pas avoir de sens pour moi (dans mon contexte) parce que je sais quel type de retour est et je voudrais écrire un code qui fera le casting pour moi. C'est peut-être un cas de génériques, je ne le sais pas encore.

C'est comme je peux assurer dans cette propriété que j'obtiens le bon objet et dans le bon type et suis 100% capable de le mouler au type de propriété. Tout ce que j'ai besoin de faire ceci pour que je n'aie pas besoin de spécifier dans chaque propriété qu'il doit "jeter une valeur à CustomClass", je voudrais faire quelque chose comme "jeter la valeur à la même classe que cette propriété est".

Par exemple:

class MYBaseClass 
{ 
    protected List<Object> MyInternalObjects; 
} 

class MyClass 
{ 
    public SpecialClass MyVeryOwnSpecialObject 
    { 
     get 
     { 
      return (SpecialClass) MyInteralObjects["MyVeryOwnSpecialObject"]; 
     } 
    } 
} 

Et ok - Je peux faire beaucoup de propriétés comme celui-ci ci-dessus - mais il y a 2 problèmes:

1) Je dois spécifier le nom de l'objet sur MyInternalObjects mais il est le même comme nom de propriété. Cela j'ai résolu avec System.Reflection.MethodBase.GetCurrentMethod(). Name.

2) Dans chaque propriété, je dois convertir un objet de MyInternalObjects en différents types. Dans MyVeryOwnSpecialObject par exemple - à SpecialClass. C'est toujours la même classe que la propriété.

Voilà pourquoi je voudrais faire quelque chose comme ceci:

class MYBaseClass 
{ 
    protected List<Object> MyInternalObjects; 
} 

class MyClass 
{ 
    public SpecialClass MyVeryOwnSpecialObject 
    { 
     get 
     { 
      return (GetPropertyType()) MyInteralObjects[System.Reflection.MethodBase.GetCurrentMethod().Name]; 
     } 
    } 
} 

Et maintenant: préoccupations Ok, pour quoi? Parce que plus loin dans mon application, je vais avoir tous les avantages des types de sécurité et ainsi de suite (IntelliSense).

Deuxième: mais maintenant vous allez perdre la sécurité de type dans cet endroit? Non.Parce que je suis très sûr que j'ai un objet de mon type sur une liste.

+0

J'ai mis à jour ma réponse pour répondre à votre modification. Je suppose que nous aurons besoin de voir un exemple * complet * pour que cette question ait du sens. –

+0

"C'est toujours la même classe que la propriété" - alors jetez-le à ce type! Vous connaissez ce type à la compilation; Pourquoi faire autre chose? Juste pour sauver un peu de frappe? –

+0

Si vous sortez de la boîte, vous verrez des avantages de ce –

Répondre

10
Object o = (TargetType) ex; 

Ce code est inutile. Vous avez peut-être un type sur la droite mais ce n'est toujours qu'un objet sur le côté gauche. Vous ne pouvez pas utiliser une fonctionnalité spécifique à TargetType comme ceci.


Voici comment vous pouvez appeler une méthode d'un objet inconnu d'un type donné:

object myObject = new UnknownType(); 
Type t = typeof(UnknownType); // myObject.GetType() would also work 
MethodInfo sayHelloMethod = t.GetMethod("SayHello"); 
sayHelloMethod.Invoke(myObject, null); 

Avec cette classe UnknownType:

class UnknownType 
{ 
    public void SayHello() 
    { 
     Console.WriteLine("Hello world."); 
    } 
} 
+0

Je dois lancer ex pour taper mon 'TargetType' personnalisé. Que proposez-vous pour cela? –

+0

Vous devrez invoquer des méthodes (ou ce que vous voulez faire) par réflexion. Je vais essayer de trouver un exemple. – weiqure

+0

J'ai mis à jour la question pour montrer le contexte –

0
if (ex is ExampleClass) 
{ 
    ExampleClass myObject = (ExampleClass)ex; 
} 

Ce serait faire mais je suppose que la question est ce que vous essayez d'atteindre et pourquoi? Je trouve souvent que si quelque chose semble vraiment, vraiment difficile alors je me trompe probablement.

+0

J'ai mis à jour la question pour montrer le contexte –

3

Généralement, un désir de faire cela indique un malentendu. Cependant, sont raisons très occasionnellement légitimes de le faire. Cela dépend si oui ou non ça va être une conversion de référence vs une conversion unboxing ou définie par l'utilisateur.

S'il s'agit d'une conversion de référence, cela signifie que la valeur réelle (la référence) restera entièrement inchangée. Tout le casting effectue une vérification, puis copie la valeur. Cela n'a aucune utilité réelle - vous pouvez effectuer la vérification en utilisant Type.IsAssignableFrom à la place, et utilisez simplement la distribution implicite à object si vous le souhaitez dans une variable de type object.

Le principal point de coulée est de fournir le compilateur avec plus d'informations. Maintenant, si vous connaissez seulement le type à exécution temps, cela ne peut clairement pas aider le compilateur.

Que comptez-vous faire avec o après avoir réalisé la distribution? Si vous pouvez expliquer cela, nous pouvons essayer d'expliquer comment obtenir l'effet que vous recherchez.

Si vous voulez vraiment une conversion définie par l'utilisateur ou une conversion unboxing de se produire, cela pourrait être une autre affaire - mais je suspect ce n'est pas le cas.

EDIT: Après avoir vu votre mise à jour, votre propriété est simplement déclaré retourner CustomClass, donc tout ce dont vous avez besoin est:

public CustomClass MyClassOuter 
{ 
    get 
    { 
     return (CustomClass) otherClass; 
    } 
} 

je soupçonne que vous avez toujours pas nous vraiment donné toutes les informations dont nous avons besoin. Est-ce définitivement comment votre propriété sera définie, avec CustomClass étant un type défini? Pourquoi avez-vous essayé d'effectuer le casting dynamiquement lorsque vous connaissez le type de propriété?

EDIT: Il semble que vous essayiez simplement d'économiser du texte - pour le rendre plus facile à couper et à coller. Ne pas. Vous connaissez le type au moment de la compilation, car vous connaissez le type de la propriété à la compilation (il est spécifié dans le code à quelques lignes plus haut). Utilisez ce type directement. De même, n'essayez pas d'obtenir le nom de la méthode actuelle pour déterminer la clé à utiliser. Il suffit de mettre le nom directement. Encore une fois, vous le savez à la compilation, alors pourquoi être dynamique?Je suis tout pour la paresse quand cela a du sens, mais dans ce cas, ce n'est pas le cas.

+0

J'ai mis à jour la question pour montrer le contexte –

+0

J'ai mis à jour ma réponse pour répondre. –

+0

Il se peut que je manque le point ici, mais il semble qu'il essaie de créer un 'get' générique pour les propriétés de n'importe quelle classe. Étant donné que les propriétés ne sont pas nommées, je ne vois pas comment cela pourrait fonctionner mais je suis heureux d'être éduqué ici. – Lazarus

1

Je ne suis pas tout à fait sûr de ce que vous essayez de faire , mais l'impression que je reçois est que vous aimeriez avoir une seule instance d'un objet qui peut "agir comme" de nombreux types d'objets différents, et vous voulez avoir des getters qui vous permettront de voir cet objet dans ces différentes manières très facilement. Dans ce cas, je suggère de faire une seule méthode getter (et non une propriété), comme suit:

public T Get<T>() 
{ 
    return (T)myObject; 
} 

Ensuite, vous l'appeler comme ceci:

Foo foo = box.Get<Foo>(); 
Bar bar = box.Get<Bar>(); 
// etc... 

Deux choses à noter: c'est Certainement pas de type sécurisé, puisque vous pouvez passer n'importe quel type pour T, y compris les types pour lesquels la distribution échouera. Vous pouvez contraindre un peu, comme si:

public T Get<T>() where T : SomeBaseType 

Ce qui provoquera une erreur de compilation si vous essayez d'utiliser un type qui est incompatible avec SomeBaseType, mais je ne suis pas sûr que ce soit tout à fait robuste. Mais j'espère que cela vous mènera le plus loin possible.

Est-ce ce que vous aviez en tête?

Questions connexes