diff --git a/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Delegate.fs b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Delegate.fs new file mode 100644 index 00000000000..fb868073b38 --- /dev/null +++ b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Delegate.fs @@ -0,0 +1,25 @@ +module Delegate + +// +open System.IO + +type WriteMethod = delegate of unit -> bool + +type OutputTarget() = + member _.SendToFile() = + try + let fn = Path.GetTempFileName() + use sw = new StreamWriter(fn) + sw.WriteLine "Hello, World!" + true + with _ -> + false + +let output = new OutputTarget() +let methodCall = WriteMethod output.SendToFile +if methodCall.Invoke() then + printfn "Success!" +else + printfn "File write operation failed." + +// \ No newline at end of file diff --git a/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Example.fs b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Example.fs new file mode 100644 index 00000000000..e1458f5e87a --- /dev/null +++ b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Example.fs @@ -0,0 +1,45 @@ +module Example + +// +open System + +type LazyValue<'T>(func: Func<'T>) = + let mutable value = ValueNone + + member _.Value = + match value with + | ValueSome v -> v + | ValueNone -> + // Execute the delegate. + let v = func.Invoke() + value <- ValueSome v + v + +let expensiveOne () = + printfn "\nExpensiveOne() is executing." + 1 + +let expensiveTwo (input: string) = + printfn "\nExpensiveTwo() is executing." + int64 input.Length + +// Note that each lambda expression has no parameters. +let lazyOne = LazyValue(fun () -> expensiveOne ()) +let lazyTwo = LazyValue(fun () -> expensiveTwo "apple") + +printfn "LazyValue objects have been created." + +// Get the values of the LazyValue objects. +printfn $"{lazyOne.Value}" +printfn $"{lazyTwo.Value}" + + +// The example produces the following output: +// LazyValue objects have been created. +// +// ExpensiveOne() is executing. +// 1 +// +// ExpensiveTwo() is executing. +// 5 +// \ No newline at end of file diff --git a/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Func1.fs b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Func1.fs new file mode 100644 index 00000000000..a5944505414 --- /dev/null +++ b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Func1.fs @@ -0,0 +1,24 @@ +module Func1 + +// +open System +open System.IO + +type OutputTarget() = + member _.SendToFile() = + try + let fn = Path.GetTempFileName() + use sw = new StreamWriter(fn) + sw.WriteLine "Hello, World!" + true + with _ -> + false + +let output = OutputTarget() +let methodCall = Func output.SendToFile +if methodCall.Invoke() then + printfn "Success!" +else + printfn "File write operation failed." + +// \ No newline at end of file diff --git a/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Lambda.fs b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Lambda.fs new file mode 100644 index 00000000000..5dd484982e5 --- /dev/null +++ b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Lambda.fs @@ -0,0 +1,23 @@ +module Lambda + +// +open System +open System.IO + +type OutputTarget() = + member _.SendToFile() = + try + let fn = Path.GetTempFileName() + use sw = new StreamWriter(fn) + sw.WriteLine "Hello, World!" + true + with _ -> + false + +let output = OutputTarget() +let methodCall = Func(fun () -> output.SendToFile()) +if methodCall.Invoke() then + printfn "Success!" +else + printfn "File write operation failed." +// \ No newline at end of file diff --git a/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/fs.fsproj b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/fs.fsproj new file mode 100644 index 00000000000..77b73617f71 --- /dev/null +++ b/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/fs.fsproj @@ -0,0 +1,12 @@ + + + Exe + net6.0 + + + + + + + + \ No newline at end of file diff --git a/xml/System/Func`1.xml b/xml/System/Func`1.xml index dc0be67403a..f2e37b10beb 100644 --- a/xml/System/Func`1.xml +++ b/xml/System/Func`1.xml @@ -77,25 +77,28 @@ 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. > [!NOTE] -> 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 delegate instead. +> 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 delegate instead. When you use the 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. :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Func~1/cs/Delegate.cs" interactive="try-dotnet" id="Snippet1"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Delegate.fs" id="Snippet1"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Func~1/vb/Delegate.vb" id="Snippet1"::: The following example simplifies this code by instantiating the delegate instead of explicitly defining a new delegate and assigning a named method to it. :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Func~1/cs/Func1.cs" interactive="try-dotnet" id="Snippet2"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Func1.fs" id="Snippet2"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Func~1/vb/Func1.vb" id="Snippet2"::: You can use the 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).) :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Func~1/cs/Anon.cs" interactive="try-dotnet" id="Snippet3"::: - You can also assign a lambda expression to a 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).) + You can also assign a lambda expression to a 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/).) :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Func~1/cs/Lambda.cs" interactive="try-dotnet" id="Snippet4"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Lambda.fs" id="Snippet4"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Func~1/vb/Lambda.vb" id="Snippet4"::: 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 namespace have `Func` parameters, you can pass these methods a lambda expression without explicitly instantiating a `Func` delegate. @@ -110,13 +113,16 @@ 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. :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/system.Func~1/cs/Example.cs" interactive="try-dotnet" id="Snippet5"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_CLR_System/system.Func~1/fs/Example.fs" id="Snippet5"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Func~1/vb/Example.vb" id="Snippet5"::: ]]> Lambda Expressions (C# Programming Guide) + Lambda Expressions: The fun Keyword (F#) Lambda Expressions Delegates (C# Programming Guide) + Delegates (F#) Delegates in Visual Basic