10
([MyCustomAttribute(...)] param1, param2) =>
{
    ...

where param1 is Type1 and param2 is Type2

It seems to me this is exactly the same as

private void method blah([MyCustomAttribute(...)] Type1 param1, Type2 param2)
{
    ...

But the first version is not allowed by the C# compiler. Why? Is this another one of those time vs effort/payback things? Isn't this just plain inconsistent?

4
  • 4
    Just out of curiosity, why would you need to attribute a parameter on an anonymous method? Commented May 15, 2013 at 18:05
  • 1
    I need to (type)annotate one of the parameters which is an untyped, unmanaged block of memory, but actually might be float[], float2[], float4[] etc. Elsewhere in my code, this type annotation is used for unit testing and data-dumping (in a human readable format). Commented May 15, 2013 at 18:15
  • You'd probably be better off just making a concrete method rather than an anonymous one. Commented May 15, 2013 at 19:26
  • True - and this is my work around. But I am curious to know why something SO equivalent on the face of it would be broken in the C# compiler. Is it a bug? Did someone think this though and say, naah !? Commented May 15, 2013 at 20:51

2 Answers 2

8

Why?

As I am fond of pointing out, the language design team does not have to provide a justification for not doing a feature. Rather, people who want features have to justify them.

If you were to ask a more targeted question instead of a vague "why?" you might ask:

If I were to pitch this feature to the C# design team, what problems would they identify with it?

There is no requirement in the C# language that lambdas be implemented as methods of a class at all.

First of all, they could be expression trees, in which case, what sense does it make to have an attribute there? And second, there is no requirement that a lambda be implemented as a method of a compiler-generated closure class, which means that there's no requirement that the parameter list even be something that you can sensibly put metadata on. Attributes are part of the metadata of the program, and one does not normally think of browsing compiler-generated types to consume their metadata as a sensible thing to do.

A strange but perfectly workable implementation of expression lambdas, for example, would be to generate the expression tree always, and then if it turned out to not be an expression tree lambda, generate a call to Compile out the other end. No metadata, so no place to put the attribute.

That would be strange, but the C# language has been carefully designed so that certain features like lambdas do not constrain the compiler writer to a particular implementation.

Is this another one of those time vs effort/payback things?

Yes.

Did someone think this though and say, naah !?

Not to my knowledge.

As I frequently point out, in order for a feature to be implemented it has to be thought of. To my knowledge you're the first person to ever think that an attribute on a lambda parameter is a good idea. Ideas that don't get thought of don't get designed, implemented, tested, documented or shipped.

Isn't this just plain inconsistent?

I suppose so.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the answer. Please note that my vague "why" was based on the assumption that there was a deep, dark and mysterious reason something like this was omitted. In it's absence, "If I were to pitch this feature to the C# design team, what problems would they identify with it?" is probably more appropriate. I will submit this as a bug/feature request on the Microsoft Connect website. Thanks again!
I ran into a situation recently where it would have been very helpful to be able to decorate a lambda with a method-level attribute (in my case the DebuggerNonUserCode attribute- to prevent expected IOExceptions being thrown and caught in the lambda from breaking the debugger).
0

The feature you are asking for is now available from C# 10.

It is now possible to put attributes both on the lambda itself:

UseCallback([SomeAttribute)(a, b) => a + b);

...and on the individual parameters:

UseCallback(([OneAttr] a, [OtherAttr] b) => a * b);

Source: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-expressions#attributes

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.