2009-08-19 5 views
1

Mise à jour Désolé. Je ne voulais pas dire que toute la bibliothèque de réflexion était interdite. Je voulais juste dire le truc incroyablement lent * .Invoke().C# Property System

Salut,

je dois mettre en place un système de propriété en C# qui permet à la fois accès à la propriété normale

[property_attribute()] 
return_type Property { get; set; } 

et l'accès par chaîne

SetProperty(string name, object value); 
object GetProperty(string name); 

Cependant,

  1. Je ne veux pas enregistrer chaque propriété individuellement.
  2. Je ne veux pas utiliser la réflexion
  3. Je ne veux pas accéder aux propriétés à travers un dictionnaire (pas de PropertyTable["abc"]=val;)

Ce schéma est nécessaire pour un système informatique de cluster où je avoir à définir les propriétés à distance et localement. Toutes les propriétés auront un attribut personnalisé qui sera lu à l'initialisation. J'espère obtenir des performances d'exécution constantes.

Actuellement, mon idée est d'avoir une analyse syntaxique analyseur/de preprocesser personnalisé/compiler les scripts en cours d'exécution et de générer l'ensemble/obtenir le code comme suit:

object GetProperty(string name) 
{ 
    if(name = "blah") 
      return Property1; 
    ... 
} 
... 

Cependant, je ne serai pas en mesure de débogage le code avec ce schéma. Quelqu'un peut-il penser à une solution?

Merci

+3

Pas si vous supprimez toutes les options. –

+0

Il y a beaucoup d'options qu'il n'a pas éliminées, la plupart impliquant certaines sortes de génération de code. – LorenVS

Répondre

2

Votre meilleure option est de générer une méthode dynamique à l'exécution en utilisant System.Reflection.Emit. Vous obtiendrez d'excellentes performances, et une fois que vous l'avez fait fonctionner correctement, le débogage ne devrait pas poser de problème. (Vous devriez pouvoir en dépendre, je ne vois pas pourquoi).

Je préfère l'approche de méthode dynamique car elle ne dépend pas de la génération de code au moment de la compilation ou du marquage d'attribut ou quoi que ce soit de ce genre. Vous pouvez le faire fonctionner sur n'importe quel objet et il fonctionnera pour toutes les propriétés publiques gablables/réglables pour cet objet.

+0

Une idée intéressante. – jameszhao00

+0

+1 La génération dynamique de méthodes semble être la solution. Si vous avez peur d'utiliser System.Reflection.Emit comme je suis, je vous suggère d'utiliser Expression Trees (http://msdn.microsoft.com/fr-fr/library/bb397951.aspx). En interne, ils utilisent aussi DynamicMethod. – jpbochi

+0

Oui, après avoir testé votre idée DynamicMethod semble être le meilleur. Il maintient les performances natives sans vous obliger à créer tous ces délégués stub avec les différents types (contrairement à l'option CreateDelegate que j'ai décrite ci-dessus) – jameszhao00

1

Vous pouvez essayer PostSharp pour créer ces attributs et demander à la classe d'implémenter l'interface getter/setter. Techniquement, il utilise la réflexion, mais il crée des assemblages au moment de la compilation, donc ce n'est pas la manière typique de System.Relfection. Si votre objectif principal est de le faire à distance, vous devrez tout de même configurer une sorte de service Web, ou service WCF, auquel cas vous aurez un proxy, ce proxy peut à son tour utiliser l'infrastructure mentionnée pour définir les attributs . Les services Web utilisent de toute façon la réflexion de toute façon, donc il n'y a pas moyen de contourner cela.

+0

Merci pour ce lien. J'utiliserai une solution MPI personnalisée intégrée à l'exécution mono via des "appels internes". – jameszhao00

1

Je pense qu'il sera difficile de trouver une bonne solution qui n'utilise pas DynamicMethod.

Comme je l'ai commenté la réponse de LorenVS, vous pouvez utiliser DynamicMethod indirectement par Expression Trees.

J'ai implémenté un générateur de délégué simple en utilisant des arbres d'expression. Il se trouve sur code.google.com. Vous pouvez donc le consulter: LateBoundMethodFactory.cs. Il manque toujours la documentation appropriée, mais le code y est bien commenté (beaucoup plus que d'habitude).

Mise à jour: lien mis à jour

+0

Malheureusement, je ne pense pas que j'aurai accès à Linq. – jameszhao00

0

Si vous ne souhaitez enregistrer la propriété individuelle echerchez, vous pouvez opter pour l'approche suivante ..

SetPropertyValue protected void & LTV & gt (chaîne propertyName, la valeur V { ViewState [propertyName] = valeur; }

protégé V GetPropertyValue & LTV & gt (chaîne propertyName, V nullValue) {// Ici nullValue peut être string.Empty ou vrai || false ou 0 etc .... // la valeur par défaut que nous voulons retourner si ViewState [propertyName] est null .... if (ViewState [propertyName] == null) { return nullValue; } return (V) ViewState [propertyName]; }

+0

Je ne souhaite pas accéder aux propriétés via un dictionnaire (c'est-à-dire sans PropertyTable ["abc"] = val;) – jameszhao00