-4

I have a method that takes an Action<> as a parameter. The parameter can be default, but how do I initialize the parameter with local parameter?

Code:

public static IServiceCollection AddAssetsSecure(this IServiceCollection services, Action<IdentityOptions> identity = default)
{
    if (identity == default)
    {
        identity.Invoke(Statics.DefaultIdentityOptions); // throws null exception
    }

    return services
        .AddAssetsIdentity(identity);
}
Peter Duniho
  • 62,751
  • 5
  • 84
  • 120
SteinTheRuler
  • 2,256
  • 17
  • 49
  • *The parameter can be default* - What exactly does this mean to you? Are you intentionally differentiating between `default` and `null`? – Kirk Larkin Oct 12 '19 at 21:44
  • A default ``Action`` is always ``null``, and you cannot call the `.Invoke` on ``null``. What do you want to do when the passed Action is `null`? – Corentin Pane Oct 12 '19 at 21:44
  • @KirkLarkin I try to use default instead of null. but that's not the issue. how do I initialize the variable if default or null? – SteinTheRuler Oct 12 '19 at 21:46
  • As @CorentinPane points out, if `identity` is `null` then you can't invoke it at all. The question is more about what code do you expect to run when `identity` is `null`? – Kirk Larkin Oct 12 '19 at 21:47
  • @CorentinPane if null or default I want to initialize the variable with a custom variable of type IdentityOptions – SteinTheRuler Oct 12 '19 at 21:48
  • which variable do you want to initialize? `identity` is of type `Action<>`, you cannot assign it a value of type `IdentityOptions`. – Corentin Pane Oct 12 '19 at 21:49
  • @CorentinPane if default or null, initliaze the Action variable with a local variable of type IdentityOptions – SteinTheRuler Oct 12 '19 at 21:49
  • @CorentinPane identity is of type Action. I have a local IdentityOptions variable that I want to assign to Action – SteinTheRuler Oct 12 '19 at 21:51
  • This is not possible because they don't have the same type. You can only assign values of type ``Action`` to ``identity``. – Corentin Pane Oct 12 '19 at 21:52
  • @CorentinPane the local variable I want to use if of type IdentityOptions – SteinTheRuler Oct 12 '19 at 21:54
  • 1
    ``Action`` is a different type than ``IdentityOptions``. You can't mix them. – Corentin Pane Oct 12 '19 at 21:57
  • I guess you want to allow the caller of `AddAssetsSecure` to provide a delegate that will set up the options. If no `identity` argument is provided, you want to use `Statics.DefaultIdentityOptions` _instead_, right? It looks like you're sort of trying to use the [Options pattern](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-3.0). – Kirk Larkin Oct 12 '19 at 21:58
  • @KirkLarkin yes! if default or null, identity = new Action(). but without passing in method with void return – SteinTheRuler Oct 12 '19 at 22:01
  • It doesn't really work that way. Once you start using the options pattern, you can't just give it an instance of the options type. You'd need to have a delegate that sets the values rather than trying to use an instance that has all the values set on it. – Kirk Larkin Oct 12 '19 at 22:06
  • @KirkLarkin ah ok. I'll try to recode it – SteinTheRuler Oct 12 '19 at 22:09
  • As everyone has noted, the default value of an `Action` is null. If you want to use an Action of your own making, it would look something like `(io) => DoSomethingWith(io)` where DoSomethingWith is a void function that takes an `IdentityOptions` as a parameter – Flydog57 Oct 12 '19 at 23:16

2 Answers2

0

To assign a value to Action<T> you need some sort of delegate with matching signature. You can't assign some other arbitrary value, including value of type T.

It's unclear what exactly you want to do in case null (default) is passed in - likely the most basic delegate - no-op that take necessary arguments (one in this case) and do nothing - would do. Combining with null coalescing operator to check for null you get:

identity = identity ?? ( _ => {});

And for whole method you can just inline that:

public static IServiceCollection AddAssetsSecure(
        this IServiceCollection services, Action<IdentityOptions> identity = default)
{
     return services.AddAssetsIdentity(identity ?? ( _ => {}));
}
Alexei Levenkov
  • 94,391
  • 12
  • 114
  • 159
-1

looks like this works:

if (identity == default)
{
    identity = (IdentityOptions) => { };
    identity.Invoke(Statics.DefaultIdentityOptions);
}
SteinTheRuler
  • 2,256
  • 17
  • 49
  • The `default` of *any* delegate is `null`, btw. – Dai Oct 12 '19 at 23:36
  • @Dai jepp that's true – SteinTheRuler Oct 12 '19 at 23:38
  • 1
    You seem to expect something useful to happen from invoking method that does absolutely nothing... What exactly do you expect from `identity.Invoke(Statics.DefaultIdentityOptions);` call shown in this answer? – Alexei Levenkov Oct 12 '19 at 23:44
  • @AlexeiLevenkov that the values in Statics.DefaultIdentityOptions to be used to configure the service – SteinTheRuler Oct 12 '19 at 23:48
  • 2
    What makes you believe so? `_=>{}` ignores its parameter and does not do anything at all (`{}` just does nothing)... There is absolutely nothing going to change whether you call `identity.Invoke(Statics.DefaultIdentityOptions);` on no-op or not... – Alexei Levenkov Oct 12 '19 at 23:53