Skip to content

Commit 781ebb1

Browse files
authored
Func<TResult> F# snippets (#7607)
1 parent 5361fe1 commit 781ebb1

File tree

6 files changed

+137
-2
lines changed

6 files changed

+137
-2
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module Delegate
2+
3+
// <Snippet1>
4+
open System.IO
5+
6+
type WriteMethod = delegate of unit -> bool
7+
8+
type OutputTarget() =
9+
member _.SendToFile() =
10+
try
11+
let fn = Path.GetTempFileName()
12+
use sw = new StreamWriter(fn)
13+
sw.WriteLine "Hello, World!"
14+
true
15+
with _ ->
16+
false
17+
18+
let output = new OutputTarget()
19+
let methodCall = WriteMethod output.SendToFile
20+
if methodCall.Invoke() then
21+
printfn "Success!"
22+
else
23+
printfn "File write operation failed."
24+
25+
// </Snippet1>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
module Example
2+
3+
// <Snippet5>
4+
open System
5+
6+
type LazyValue<'T>(func: Func<'T>) =
7+
let mutable value = ValueNone
8+
9+
member _.Value =
10+
match value with
11+
| ValueSome v -> v
12+
| ValueNone ->
13+
// Execute the delegate.
14+
let v = func.Invoke()
15+
value <- ValueSome v
16+
v
17+
18+
let expensiveOne () =
19+
printfn "\nExpensiveOne() is executing."
20+
1
21+
22+
let expensiveTwo (input: string) =
23+
printfn "\nExpensiveTwo() is executing."
24+
int64 input.Length
25+
26+
// Note that each lambda expression has no parameters.
27+
let lazyOne = LazyValue(fun () -> expensiveOne ())
28+
let lazyTwo = LazyValue(fun () -> expensiveTwo "apple")
29+
30+
printfn "LazyValue objects have been created."
31+
32+
// Get the values of the LazyValue objects.
33+
printfn $"{lazyOne.Value}"
34+
printfn $"{lazyTwo.Value}"
35+
36+
37+
// The example produces the following output:
38+
// LazyValue objects have been created.
39+
//
40+
// ExpensiveOne() is executing.
41+
// 1
42+
//
43+
// ExpensiveTwo() is executing.
44+
// 5
45+
// </Snippet5>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module Func1
2+
3+
// <Snippet2>
4+
open System
5+
open System.IO
6+
7+
type OutputTarget() =
8+
member _.SendToFile() =
9+
try
10+
let fn = Path.GetTempFileName()
11+
use sw = new StreamWriter(fn)
12+
sw.WriteLine "Hello, World!"
13+
true
14+
with _ ->
15+
false
16+
17+
let output = OutputTarget()
18+
let methodCall = Func<bool> output.SendToFile
19+
if methodCall.Invoke() then
20+
printfn "Success!"
21+
else
22+
printfn "File write operation failed."
23+
24+
// </Snippet2>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module Lambda
2+
3+
// <Snippet4>
4+
open System
5+
open System.IO
6+
7+
type OutputTarget() =
8+
member _.SendToFile() =
9+
try
10+
let fn = Path.GetTempFileName()
11+
use sw = new StreamWriter(fn)
12+
sw.WriteLine "Hello, World!"
13+
true
14+
with _ ->
15+
false
16+
17+
let output = OutputTarget()
18+
let methodCall = Func<bool>(fun () -> output.SendToFile())
19+
if methodCall.Invoke() then
20+
printfn "Success!"
21+
else
22+
printfn "File write operation failed."
23+
// </Snippet4>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="Delegate.fs" />
8+
<Compile Include="Func1.fs" />
9+
<Compile Include="Lambda.fs" />
10+
<Compile Include="Example.fs" />
11+
</ItemGroup>
12+
</Project>

xml/System/Func`1.xml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,25 +77,28 @@
7777
You can use this delegate to represent a method that can be passed as a parameter without explicitly declaring a custom delegate. The encapsulated method must correspond to the method signature that is defined by this delegate. This means that the encapsulated method must have no parameters and must return a value.
7878
7979
> [!NOTE]
80-
> To reference a method that has no parameters and returns `void` (or in Visual Basic, that is declared as a `Sub` rather than as a `Function`), use the <xref:System.Action> delegate instead.
80+
> To reference a method that has no parameters and returns `void` (`unit`, in F#) (or in Visual Basic, that is declared as a `Sub` rather than as a `Function`), use the <xref:System.Action> delegate instead.
8181
8282
When you use the <xref:System.Func%601> delegate, you do not have to explicitly define a delegate that encapsulates a parameterless method. For example, the following code explicitly declares a delegate named `WriteMethod` and assigns a reference to the `OutputTarget.SendToFile` instance method to its delegate instance.
8383
8484
:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Func~1/cs/Delegate.cs" interactive="try-dotnet" id="Snippet1":::
85+
:::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Delegate.fs" id="Snippet1":::
8586
:::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Func~1/vb/Delegate.vb" id="Snippet1":::
8687
8788
The following example simplifies this code by instantiating the <xref:System.Func%601> delegate instead of explicitly defining a new delegate and assigning a named method to it.
8889
8990
:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Func~1/cs/Func1.cs" interactive="try-dotnet" id="Snippet2":::
91+
:::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Func1.fs" id="Snippet2":::
9092
:::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Func~1/vb/Func1.vb" id="Snippet2":::
9193
9294
You can use the <xref:System.Func%601> delegate with anonymous methods in C#, as the following example illustrates. (For an introduction to anonymous methods, see [Anonymous Methods](/dotnet/csharp/programming-guide/statements-expressions-operators/anonymous-methods).)
9395
9496
:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Func~1/cs/Anon.cs" interactive="try-dotnet" id="Snippet3":::
9597
96-
You can also assign a lambda expression to a <xref:System.Func%602> delegate, as the following example illustrates. (For an introduction to lambda expressions, see [Lambda Expressions](/dotnet/visual-basic/programming-guide/language-features/procedures/lambda-expressions) and [Lambda Expressions](/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions).)
98+
You can also assign a lambda expression to a <xref:System.Func%602> delegate, as the following example illustrates. (For an introduction to lambda expressions, see [Lambda Expressions (VB)](/dotnet/visual-basic/programming-guide/language-features/procedures/lambda-expressions), [Lambda Expressions (C#)](/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions), and [Lambda Expressions (F#)](/dotnet/fsharp/language-reference/functions/lambda-expressions-the-fun-keyword/).)
9799
98100
:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Func~1/cs/Lambda.cs" interactive="try-dotnet" id="Snippet4":::
101+
:::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Lambda.fs" id="Snippet4":::
99102
:::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Func~1/vb/Lambda.vb" id="Snippet4":::
100103
101104
The underlying type of a lambda expression is one of the generic `Func` delegates. This makes it possible to pass a lambda expression as a parameter without explicitly assigning it to a delegate. In particular, because many methods of types in the <xref:System.Linq> namespace have `Func` parameters, you can pass these methods a lambda expression without explicitly instantiating a `Func` delegate.
@@ -110,13 +113,16 @@
110113
The example creates two methods and instantiates two `LazyValue` objects with lambda expressions that call these methods. The lambda expressions do not take parameters because they just need to call a method. As the output shows, the two methods are executed only when the value of each `LazyValue` object is retrieved.
111114
112115
:::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Func~1/cs/Example.cs" interactive="try-dotnet" id="Snippet5":::
116+
:::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Example.fs" id="Snippet5":::
113117
:::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Func~1/vb/Example.vb" id="Snippet5":::
114118
115119
]]></format>
116120
</remarks>
117121
<related type="Article" href="/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions">Lambda Expressions (C# Programming Guide)</related>
122+
<related type="Article" href="/dotnet/fsharp/language-reference/functions/lambda-expressions-the-fun-keyword">Lambda Expressions: The fun Keyword (F#)</related>
118123
<related type="Article" href="/dotnet/visual-basic/programming-guide/language-features/procedures/lambda-expressions">Lambda Expressions</related>
119124
<related type="Article" href="/dotnet/csharp/programming-guide/delegates/">Delegates (C# Programming Guide)</related>
125+
<related type="Article" href="/dotnet/fsharp/language-reference/delegates/">Delegates (F#)</related>
120126
<related type="Article" href="/dotnet/visual-basic/programming-guide/language-features/delegates/">Delegates in Visual Basic</related>
121127
</Docs>
122128
</Type>

0 commit comments

Comments
 (0)