c# crée - Fonctions en ligne en C #?




7 Answers

Enfin dans .NET 4.5, le CLR permet de suggérer / suggérer une méthode en utilisant la méthode MethodImplOptions.AggressiveInlining. Il est également disponible dans le coffre du Mono (commis aujourd'hui).

// The full attribute usage is in mscorlib.dll,
// so should not need to include extra references
using System.Runtime.CompilerServices; 

...

[MethodImpl(MethodImplOptions.AggressiveInlining)]
void MyMethod(...)

1 . Auparavant, "force" était utilisée ici. Comme il y avait quelques downvotes, je vais essayer de clarifier le terme. Comme dans les commentaires et la documentation, The method should be inlined if possible. Surtout en considérant Mono (qui est ouvert), il y a quelques limitations techniques mono-spécifiques considérant inlining ou plus générales (comme des fonctions virtuelles). Dans l'ensemble, oui, c'est un indice à compiler, mais je suppose que c'est ce qui a été demandé.

formation open

Comment faites-vous les "fonctions en ligne" en C #? Je ne pense pas comprendre le concept. Sont-ils comme des méthodes anonymes? Comme les fonctions lambda?

Note : Les réponses traitent presque entièrement de la capacité à intégrer des fonctions , c.-à-d. «Une optimisation manuelle ou du compilateur qui remplace un site d'appel de fonction par le corps de l'appelé». Si vous êtes intéressé par les fonctions anonymes (aka lambda) , consultez la réponse de @ jalf ou Qu'est-ce que c'est "Lambda" dont tout le monde parle? .




Mise à jour: la réponse de Per konrad.kruczynski , ce qui suit est vrai pour les versions de .NET jusqu'à et y compris 4.0.

Vous pouvez utiliser la classe MethodImplAttribute pour empêcher une méthode d'être inline ...

[MethodImpl(MethodImplOptions.NoInlining)]
void SomeMethod()
{
    // ...
}

... mais il n'y a aucun moyen de faire le contraire et de le forcer à être inline.




Voulez-vous dire des fonctions inline au sens C ++? Dans lequel le contenu d'une fonction normale est automatiquement copié en ligne dans le callsite? L'effet final étant qu'aucun appel de fonction ne se produit réellement lors de l'appel d'une fonction.

Exemple:

inline int Add(int left, int right) { return left + right; }

Si oui alors non, il n'y a pas de C # équivalent à ceci.

Ou Voulez-vous dire les fonctions qui sont déclarées dans une autre fonction? Si oui alors oui, C # supporte cela via des méthodes anonymes ou des expressions lambda.

Exemple:

static void Example() {
  Func<int,int,int> add = (x,y) => x + y;
  var result = add(4,6);  // 10
}



Oui Exactement, la seule distinction est le fait qu'elle renvoie une valeur.

Simplification (n'utilisant pas d'expressions):

List<T>.ForEach une action, il n'attend pas de résultat de retour.

Un délégué Action<T> suffirait donc ...

List<T>.ForEach(param => Console.WriteLine(param));

est le même que de dire:

List<T>.ForEach(delegate(T param) { Console.WriteLine(param); });

la différence est que le type de param et la déclération de délégué sont déduits par l'utilisation et que les accolades ne sont pas requises pour une méthode en ligne simple.

Tandis que

List<T>.Where Prend une fonction, attend un résultat.

Donc, une Function<T, bool> serait attendue:

List<T>.Where(param => param.Value == SomeExpectedComparison);

qui est le même que:

List<T>.Where(delegate(T param) { return param.Value == SomeExpectedComparison; });

Vous pouvez également déclarer ces méthodes en ligne et les affecter aux variables IE:

Action myAction = () => Console.WriteLine("I'm doing something Nifty!");

myAction();

ou

Function<object, string> myFunction = theObject => theObject.ToString();

string myString = myFunction(someObject);

J'espère que ça aide.




L'affirmation "c'est mieux de laisser ces choses tranquilles et de laisser le compilateur faire le travail .." (Cody Brocious) est complètement rubish. J'ai programmé du code de jeu de haute performance pendant 20 ans, et je n'ai pas encore trouvé de compilateur qui soit assez intelligent pour savoir quel code devrait être en ligne (fonctions) ou non. Il serait utile d'avoir une instruction "inline" dans c #, la vérité est que le compilateur n'a tout simplement pas toutes les informations dont il a besoin pour déterminer quelle fonction doit toujours être inline ou non sans l'indice "inline". Bien sûr, si la fonction est petite (accesseur), elle peut être automatiquement insérée, mais qu'en est-il s'il s'agit de quelques lignes de code? Nonesense, le compilateur n'a aucun moyen de le savoir, vous ne pouvez pas laisser cela au compilateur pour le code optimisé (au-delà des algorithmes).




Dans le cas où vos assemblys seront modifiés, vous pouvez jeter un oeil à TargetedPatchingOptOut. Cela aidera ngen à décider si les méthodes doivent être intégrées. Référence MSDN

Ce n'est encore qu'un indice déclaratif à optimiser, pas une commande impérative.




C # ne supporte pas les méthodes en ligne (ou les fonctions) de la même manière que les langages dynamiques comme python. Cependant, les méthodes anonymes et les lambdas peuvent être utilisés à des fins similaires, notamment lorsque vous devez accéder à une variable dans la méthode conteneur, comme dans l'exemple ci-dessous.

static void Main(string[] args)
{
    int a = 1;

    Action inline = () => a++;
    inline();
    //here a = 2
}



Related

c# optimization inline