Paramètres optionnels dans le C++/CLI méthodes
Comment puis-je déclarer une méthode gérée en C++/CLI qui est un paramètre facultatif lorsque utilisée en C#?
J'ai décoré le paramètre à la fois d'une En option et un DefaultParameterValue attribut (voir: Comment les valeurs par défaut des paramètres sont codés), mais seulement l'attribut Facultatif semble être à l'honneur.
C++/CLI:
public ref class MyClass1
{
public:
MyClass1([System::Runtime::InteropServices::Optional]
[System::Runtime::InteropServices::DefaultParameterValue(2)]
int myParam1) ↑
{
System::Console::WriteLine(myParam1);
}
};
C#:
var myInstance1 = new MyClass1(); //compiles and runs
Sortie:
0
Résultat Attendu:
2
Visual C# IntelliSense:
MyClass1.MyClass1([int myParam1 = 0]); //wrong default value
↑
Edit: regarder de plus près, avec un désassembleur révèle que le C++/CLI compilateur n'a en effet pas à produire les .param [1] = int32(2)
directive. Le IL code indiqué par le Réflecteur est faux.
Réflecteur:
.method public hidebysig specialname rtspecialname instance void .ctor([opt] int32 myParam1) cil managed
{
.param [1] = int32(2) //bug
...
ILDASM:
.method public hidebysig specialname rtspecialname instance void .ctor([opt] int32 myParam1) cil managed
{
.param [1]
.custom instance void [System]System.Runtime.InteropServices.DefaultParameterValueAttribute::.ctor(object) = ( 01 00 08 02 00 00 00 00 00 )
...
- Pourquoi est-ce qu'une surcharge de ne pas travailler, à vos fins?
- P: Juste des raisons esthétiques. Je vais faire des surcharges quand je ne peux pas obtenir que cela fonctionne, mais je préfère les paramètres facultatifs, si possible.
Vous devez vous connecter pour publier un commentaire.
Le compilateur C# ne pas utiliser les [DefaultParameterValue] attribut pour définir la valeur par défaut, il utilise le .param directive pour obtenir la valeur incorporée dans les métadonnées. À peine documenté dans les spécifications CLI btw, seule la Partition II, chapitre 15.4.1 mentionne qu'il peut avoir un FieldInit valeur, 15.4.1.4 est silencieuse à ce sujet.
C'est là où la balle s'arrête, le C++/CLI compilateur ne sait pas comment générer de la directive. Vous ne pouvez pas faire ce travail.
You cannot make this work...
- défi accepté! Je parie que si vous avez utilisé un post-créer un événement impliquant quelque chose commeMono.Cecil
qui a réécrit un peu de métadonnées allait le faire. Pas sûr si cela va fonctionner avec C++/CLR assemblages contenant le code non managé bien.Il existe une astuce pour faire ce travail (contournement).
le mot magique est nullable, comme pour les types nullables la valeur par défaut est toujours la valeur "null" (.HasValue == false)
Exemple:
C++ CLI dans l'en-tête:
C++ CLI dans .fichier cpp:
de Test en C#:
Comme une solution de contournement, vous pouvez simplement surcharger le constructeur, et d'utiliser la délégation. Il sera incorporé par le JIT et devrait se retrouver avec le même résultat final que d'une valeur de paramètre par défaut.