Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why would you use Func<string> instead of just string?

Why would you useFunc<string> instead of just string ?

My question is specifically in regards to this repo.

The line in question is 22:

    private static Func<string> getToken = () => Environment.GetEnvironmentVariable("GitHubToken", EnvironmentVariableTarget.Process);

getToken encapsulates a method that has no parameters and returns a string. What is the reason for not simply typing this variable to be a string?

Why would you useFunc<string> instead of just string ?

like image 441
Alex Gordon Avatar asked Dec 11 '19 15:12

Alex Gordon


People also ask

What is the difference between func string string and delegate?

The basic difference between Func and Action delegates is that while the former is used for delegates that return value, the latter can be used for those delegates in which you don't have any return value.

What is the use of func keyword in C#?

Func is generally used for those methods which are going to return a value, or in other words, Func delegate is used for value returning methods. It can also contain parameters of the same type or of different types.

What is .NET func?

Func is a generic delegate included in the System namespace. It has zero or more input parameters and one out parameter. The last parameter is considered as an out parameter. The Func delegate that takes one input parameter and one out parameter is defined in the System namespace, as shown below: Signature: Func.


2 Answers

I can see five reasons one might do this:

  1. When you want to allow for a value that will not only change over time (you could still accomplish that with a property!), but the place you need to check to find it might change. For example, by default you check an environment variable, but there's a user option somewhere that will instead look in a config file, or a web service, or database table, etc. Now you can swap out the function call, rather than checking that config option every time inside a function that must know how to do all of those.
  2. It makes it just very slightly easier to use this in an async context, where you can await the results. You can await the function in a task directly, rather than having to also wrap the property as an awaitable method.
  3. They wanted function semantics rather than property semantics. This is a choice, where they wanted to present a function call as the public API for the type instead of a property. The lambda, then, (really: expression bodied member) is just a shorter way to write the method.
  4. This was written before the new default interface implementations in C# 8, where the code is providing a default implementation, but really expects you to "override" it and replace the method with your own that can look at whatever value you need. Or, even if they were using C# 8, an additional interface was seen as not worth the effort.
  5. It's easier to change out the implementation in dependancy injection scenarios, though hopefully someone doing that would be using an interface instead. Typically you inject the whole type, rather than a single method.
like image 59
Joel Coehoorn Avatar answered Oct 14 '22 09:10

Joel Coehoorn


By storing it as a Func<string>, Environment.GetEnvironmentVariable will be called each time the variable is accessed. Meaning if Environment.GetEnvironmentVariable would return a different value on subsequent calls, you'll get the new value.

As far as I can tell, the only way Environment.GetEnvironmentVariable will return a different value for the same input is if Environment.SetEnvironmentVariable is called.

like image 34
mason Avatar answered Oct 14 '22 09:10

mason