James
James

Reputation: 105

Implicit parameter modifiers with delegates? (C#)

I'm working on a library that allows users to instantiate some delegates.

I have a defined a delegate type that deals with a struct as one of its parameters, that we only need to read and not modify, so the in keyword seemed useful.

public struct SomeStruct 
{ 
    public string x; 
    // and possibly more...
}

public delegate void MyDelegate(object foo, in SomeStruct bar);

However, when I go to create it, it tells me I need to put in there.

// Parameter 2 must be declared with the 'in' keyword
MyDelegate x = (foo, bar) => System.Console.WriteLine(bar.x);

If I use in, I now have to explicitly type the parameter...

// doesn't work
MyDelegate x = (foo, in bar) => System.Console.WriteLine(bar.x);

But now that I explicitly type the second parameter, the first parameter needs to be explicit too.

// Inconsistent lambda parameter usage; parameter types must be all explicit or all implicit
MyDelegate x = (foo, in SomeStruct bar) => System.Console.WriteLine(bar.x);
// ok
MyDelegate x = (object foo, in SomeStruct bar) => System.Console.WriteLine(bar.x);

Now in my use case, the types for parameters foo and bar could have long names, generic parameters, etc.

The type information is already there where this delegate type is defined. Is there a way to avoid making my users explicitly type the parameters for this delegate?

I expected (foo, bar) => or (foo, in bar) => to work but it does not.

edit: I was playing around more and this seems to be the case for ref as well, I'm guessing for all parameter modifiers. So question name was changed from just asking about in to modifiers in general

Upvotes: 7

Views: 499

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1499730

No, you can't provide modifiers with implicit anonymous function parameters.

If you look at the grammar in the ECMA standard - which is currently for C# 6, hence the lack of the in modifier - you'll see the difference between explicit_anonymous_function_parameter which includes both an optional modifier and a type, and an implicit_anonymous_function_parameter which is just an identifier:

explicit_anonymous_function_parameter
    : anonymous_function_parameter_modifier? type Identifier
    ;

anonymous_function_parameter_modifier
    : 'ref'
    | 'out'
    ;

implicit_anonymous_function_parameter
    : Identifier
    ;

I agree this can be slightly frustrating - but I wouldn't expect to see it change any time soon.

Upvotes: 2

Related Questions