⚠ Deprecated: CriticalBugs
Weaves <PrivateImplementationDetails> which may cause issues at runtime depending on use case
Suggested alternative: StaticLambda.Fody
Emits lambdas as static methods when possible.
$ dotnet add package StaticLambda.FodyThis is an add-in for Fody which turns lambda methods static if possible.
This project has a dependency to Emik.Morsels, if you are building this project, refer to its README first.
This weaver exists because there is no way to guarantee that a lambda function will compile as a static method, even if you use the static keyword.
"No guarantee is made as to whether a static anonymous function definition is emitted as a
staticmethod in metadata. This is left up to the compiler implementation to optimize." - source
The reason is because delegates by nature are at their fastest invoking instanced methods, however in some cases it may be useful to make these methods static, mainly for reflection and interop purposes.
Of course, you can force it to be static by defining your own method to be static:
Foo(ThisInsteadOfALambda);
static void ThisInsteadOfALambda() { }
However, this may be an unsatisfactory solution as it creates far more verbose code, particularly when the parameter types are complicated and you use an API that has them inferred.
Installing this weaver will turn every applicable lambda into a static method. You do not need to specify static for this to take effect. Runtime performance is very likely barely worse with this weaver, but chances are the reflection that facillitates the need for static methods already makes this difference negligible.
Install the NuGet packages Fody and StaticLambda.Fody. Installing Fody explicitly is needed to enable weaving.
PM> Install-Package Fody
PM> Install-Package StaticLambda.Fody
Add the PrivateAssets="all" metadata attribute to the <PackageReference /> items of Fody and StaticLambda.Fody in your project file, so they won't be listed as dependencies.
If you already have a FodyWeavers.xml file in the root directory of your project, add the <StaticLambda /> tag there. This file will be created on the first build if it doesn't exist:
<Weavers>
<StaticLambda />
</Weavers>
See Fody usage for general guidelines, and Fody Configuration for additional options.
Define the compiler constant NO_STATIC_LAMBDA_FODY to skip this weaver. Useful to be passed as a command-line argument: e.g. dotnet build -define NO_STATIC_LAMBDA_FODY.
There is currently no way to define which classes or methods are affected. If you do require this level of granular control, please raise an issue, and preferably your use case.
What you write:
Capture(() => 42);
static void Capture(System.Func<int> _) { }
What gets compiled:
// The Func<int> target normally is the <>c singleton (which is now redundant)
Capture(Program.<>c.<>9__0_0 ?? (Program.<>c.<>9__0_0 = new Func<int>(null, __methodptr(<Main>b__0_0))));
static void Capture(Func<int> _) { }
[CompilerGenerated, Serializable]
private sealed class <>c
{
public static Func<int> <>9__0_0;
// This method is normally non-static.
internal static int <Main>b__0_0() => 42;
}
Issues and pull requests are welcome to help this repository be the best it can be.
This repository falls under the MPL-2 license.