2009-11-05 9 views
1

J'ai une classe:délégué invoquant des arguments génériques en C#

public class MyClass<T> 
{ 
    public string TestProperty { get; set; } 
} 

et je veux créer un délégué pour exécuter sur les instances de cette classe, tels que:

Action<MyClass<object>> myDelegate = myclass => myclass.TestProperty = "hello"; 

Cependant, la Le délégué ci-dessus ne peut pas être appelé avec autre chose qu'un MyClass<object>, tel que MyClass<DateTime> ou MyClass<string>.

Comment puis-je soit définir le délégué, ou modifier le délégué afin que je puisse exécuter le délégué sur un MyClass<T>T est quelque chose qui étend object?

Edit: Cette peut attendre que C# 4 si c'est lorsque cela devient possible (si oui, s'il vous plaît me dire encore comment), bien que je préfère passer à autre chose maintenant à 3,5

edit: J'ai fait aussi une 2ème classe:

public class MyDerivedClass<T1, T2> : MyClass<T1> 
{ 
    public int OtherProp { get; set; } 
} 

id Idéalement aiment utiliser la syntaxe suivante pour définir des délégués:

CreateDelegate<MyClass<object>>(mc => mc.TestProperty = "hello"); 
CreateDelegate<MyDerivedClass<object, object>>(mc => mc.OtherProp = 4); 

alors donné un objet, jaimerais voir quels arguments délégué correspondent, puis les exécuter

Est-ce possible? Quelles alternatives ai-je pour créer de tels délégués?

Merci

Répondre

3

Vous pouvez créer une interface pour encapsuler les membres de MyClass<T> que vous avez besoin:

interface IFoo 
{ 
    String TestProperty { get; set; } 
} 

Ensuite, changez votre délégué à utiliser cette interface:

Action<IFoo> myDelegate = myclass => myclass.TestProperty = "hello"; 

Edit: Et Évidemment, vous besoin de faire ceci aussi:

public class MyClass<T> : IFoo 
{ 
    public String TestProperty { get; set; } 
} 
+0

merci pour l'aide, voir mon commentaire @Tony et la question mise à jour –

+0

interfaces étaient la réponse, juste besoin d'arrêter d'être daft! –

4

EDIT: Après avoir réfléchi à ce sujet un peu plus loin, je ne crois pas C# 4 va réellement vous aider dans ce cas. Vous auriez besoin que le type MyClass soit lui-même une variante, mais cela ne peut pas être parce que c'est une classe. Mais ...

Vous pouvez écrire une méthode générique pour vous rendre une action spécifique:

public Action<MyClass<T>> NewTestPropertyDelegate<T>() 
{ 
    return myclass => myclass.TestProperty = "hello"; 
} 

EDIT: Je l'ai mentionné la suggestion de Andrew Hare avant - mais voici une autre alternative en utilisant une classe de base au lieu d'une interface.

public abstract class MyClass 
{ 
    public string TestProperty { get; set; } 
} 

public class MyClass<T> : MyClass 
{ 
    ... 
} 

Ensuite, utilisez Action<MyClass>.

+0

hmm merci pour l'info, on dirait que je vais avoir de la malchance. J'ai mis à jour la question avec un peu plus d'informations, je pense que je peux légèrement vous tromper en simplifiant à l'excès le problème :( –

+0

puis-je pas utiliser une expression > à la place, puis modifier l'expression au bon T quand il s'agit de l'appliquer? –

+0

@Andrew: Hmm ... peut-être pas sûr, je vais essayer de me rappeler d'avoir un autre coup d'oeil à cela plus tard –

0

Je sais que c'est un vieux message, mais j'ai pensé que cela aidera la prochaine personne qui pourrait vouloir faire cela.J'ai un peu bricolé avec cette idée parce que je trouve que c'est une caractéristique très souhaitable. Je suis arrivé aux délégués qui ont un paramètre générique de travail en procédant comme suit:

Délégué public vide AppSettingsHandlerMethodSetKeyValue (clé de la chaîne, la valeur T);

public class AppSettingsHandler

{

CacheHandler publique (AppSettingsHandlerMethodSetKeyValue setAppSettingsVariable)

{

SetApplicationSettingsVariable = (AppSettingsHandlerMethodSetKeyValue) setAppSettingsVariable;

}

interne AppSettingsHandlerMethodSetKeyValue SetApplicationSettingsVariable {get; ensemble; }

SetApplicationSetting vide interne (touche de chaîne, la valeur T)

{

SetApplicationSettingsVariable (clé, valeur);

}

}

J'espère que quelqu'un trouve cela utile. Je suis sûr que quelqu'un aura quelque chose à dire à ce sujet, mais cela fonctionne pour moi.

Questions connexes