Est-il possible de déclarer une méthode dans une autre méthode en C #?
Par exemple comme ça:
void OuterMethod()
{
int anything = 1;
InnedMethod();
void InnerMethod()
{
int PlitschPlatsch = 2;
}
}
Mise à jour: fonctions locales où ajouté dans la version 7 C #.
void OuterMethod()
{
int foo = 1;
InnerMethod();
void InnerMethod()
{
int bar = 2;
foo += bar
}
}
Dans la version précédente C #, vous devez utiliser une action comme celle-ci:
void OuterMethod()
{
int anything = 1;
Action InnedMethod = () =>
{
int PlitschPlatsch = 2;
};
InnedMethod();
}
MISE À JOUR: C # 7 a ajouté des fonctions locales ( https://docs.Microsoft.com/en-us/dotnet/articles/csharp/csharp-7#local-functions )
void OuterMethod()
{
int foo = 1;
InnerMethod();
void InnerMethod()
{
int bar = 2;
foo += bar
}
}
Dans les versions de C # avant C # 7, vous pouvez déclarer un Func
ou Action
et obtenir quelque chose de similaire:
void OuterMethod()
{
int foo = 1;
Action InnerMethod = () =>
{
int bar = 2;
foo += bar;
} ;
InnerMethod();
}
oui, il existe des moyens. Avec C # 3.0, vous avez le type Func<T>
qui fait cela.
Par exemple, j'ai écrit ceci hier:
var image = Image.FromFile(_file);
int height = image.Height;
int width = image.Width;
double tan = height*1.00/width;
double angle = (180.0 * Math.Atan(tan) / Math.PI);
var bitmap = new System.Drawing.Bitmap(image, width, height);
var g = System.Drawing.Graphics.FromImage(bitmap);
int fontsize = 26; // starting guess
Font font = null;
System.Drawing.SizeF size;
Func<SizeF,double> angledWidth = new Func<SizeF,double>( (x) =>
{
double z = x.Height * Math.Sin(angle) +
x.Width * Math.Cos(angle);
return z;
});
// enlarge for width
do
{
fontsize+=2;
if (font != null) font.Dispose();
font = new Font("Arial", fontsize, System.Drawing.FontStyle.Bold);
size = g.MeasureString(_text, font);
}
while (angledWidth(size)/0.85 < width);
Le but était d'ajouter un filigrane à une image existante. Je voulais que la taille du texte du filigrane soit d'environ 85% de la largeur de l'image. Mais je voulais incliner le texte du filigrane pour qu'il soit écrit sous un angle. Cela a révélé la nécessité de faire des calculs de trig en fonction des angles, et je voulais une petite fonction pour effectuer ce travail. Le Func
est parfait pour cela.
Le code ci-dessus définit un Func
(une fonction) qui accepte un SizeF
et renvoie un double
, pour la largeur réelle du texte lorsqu'il est dessiné à l'angle donné. Ce Func
est une variable dans une fonction, et la variable elle-même contient une (référence à une) fonction. Je peux alors invoquer cette fonction "privée" dans le cadre où je l'ai définie. Le Func a accès aux autres variables définies avant lui, dans sa portée d'exécution. Ainsi, la variable angle
est accessible dans la fonction angledWidth()
.
Si vous voulez une logique invocable qui renvoie void
, vous pouvez utiliser Action<T>
, de la même manière. .NET définit les génériques Func qui acceptent N arguments, vous pouvez donc les rendre assez compliqués. Un Func est comme une fonction VB ou une méthode C # qui retourne non vide; une action est comme un VB Sub, ou une méthode C # qui retourne vide) .
Cinq ans se sont écoulés depuis que cette question a été posée et maintenant C # 7 arrive.
Il est prévu d'inclure des fonctions locales et est apparemment déjà implémenté.
Fonctions locales (Proposition: # 259) [actuellement dans la future branche]
Le mot clé delegate
fait exactement cela.
void OuterMethod()
{
var InnerMethod = delegate()
{
int PlitschPlatsch = 2;
};
int anything = 1;
InnerMethod();
}
N'oubliez pas que, par portée, la variable PlitschPlatsch
ne sera pas accessible en dehors d'InnerMethod.
Si vous cherchez principalement à "masquer" une méthode qui n'est qu'un "assistant" ... une autre option est de rendre votre ou vos assistants private
. De cette façon, ils ne font pas partie de l'interface publique de votre classe.
Cela présente l'avantage que le ou les assistants peuvent être réutilisés si nécessaire; mais ils ne seront pas "internes" à la méthode d'appel.
Jetez un œil à méthodes anonymes . Je pense que c'est ce que vous recherchez.