From 785a124fa25a0327f45542b1567aa35efba8598e Mon Sep 17 00:00:00 2001 From: albert-du <52804499+albert-du@users.noreply.github.com> Date: Tue, 18 Jan 2022 21:07:25 -0800 Subject: [PATCH] Delegate F# snippets --- .../System/Delegate/CreateDelegate/fs.fsproj | 11 ++ .../Delegate/CreateDelegate/openClosedOver.fs | 101 ++++++++++++++ .../System/Delegate/CreateDelegate/source.fs | 126 ++++++++++++++++++ .../System/Delegate/CreateDelegate/source1.fs | 45 +++++++ .../fsharp/System/Delegate/Overview/fs.fsproj | 9 ++ .../fsharp/System/Delegate/Overview/source.fs | 35 +++++ .../fs/GetInvocationList1.fs | 43 ++++++ .../fs/fs.fsproj | 10 ++ xml/System/Delegate.xml | 12 ++ 9 files changed, 392 insertions(+) create mode 100644 samples/snippets/fsharp/System/Delegate/CreateDelegate/fs.fsproj create mode 100644 samples/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs create mode 100644 samples/snippets/fsharp/System/Delegate/CreateDelegate/source.fs create mode 100644 samples/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs create mode 100644 samples/snippets/fsharp/System/Delegate/Overview/fs.fsproj create mode 100644 samples/snippets/fsharp/System/Delegate/Overview/source.fs create mode 100644 samples/snippets/fsharp/VS_Snippets_CLR_System/System.Delegate.GetInvocationList/fs/GetInvocationList1.fs create mode 100644 samples/snippets/fsharp/VS_Snippets_CLR_System/System.Delegate.GetInvocationList/fs/fs.fsproj diff --git a/samples/snippets/fsharp/System/Delegate/CreateDelegate/fs.fsproj b/samples/snippets/fsharp/System/Delegate/CreateDelegate/fs.fsproj new file mode 100644 index 00000000000..e46caaceb79 --- /dev/null +++ b/samples/snippets/fsharp/System/Delegate/CreateDelegate/fs.fsproj @@ -0,0 +1,11 @@ + + + Exe + net6.0 + + + + + + + \ No newline at end of file diff --git a/samples/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs b/samples/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs new file mode 100644 index 00000000000..9ed094ca96a --- /dev/null +++ b/samples/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs @@ -0,0 +1,101 @@ +module openClosedOver + +// All four permutations of instance/static with open/closed. +// +// +open System +open System.Reflection + +// A sample class with an instance method and a static method. +type C(id) = + member _.M1(s) = + printfn $"Instance method M1 on C: id = %i{id}, s = %s{s}" + + static member M2(s) = + printfn $"Static method M2 on C: s = %s{s}" + +// Declare three delegate types for demonstrating the combinations +// of static versus instance methods and open versus closed +// delegates. +type D1 = delegate of C * string -> unit +type D2 = delegate of string -> unit +type D3 = delegate of unit -> unit + +let c1 = C 42 + +// Get a MethodInfo for each method. +// +let mi1 = typeof.GetMethod("M1", BindingFlags.Public ||| BindingFlags.Instance) +let mi2 = typeof.GetMethod("M2", BindingFlags.Public ||| BindingFlags.Static) + +printfn "\nAn instance method closed over C." + +// In this case, the delegate and the +// method must have the same list of argument types use +// delegate type D2 with instance method M1. +let test = Delegate.CreateDelegate(typeof, c1, mi1, false) + +// Because false was specified for throwOnBindFailure +// in the call to CreateDelegate, the variable 'test' +// contains null if the method fails to bind (for +// example, if mi1 happened to represent a method of +// some class other than C). +if test <> null then + let d2 = test :?> D2 + + // The same instance of C is used every time the + // delegate is invoked. + d2.Invoke "Hello, World!" + d2.Invoke "Hi, Mom!" + +printfn "\nAn open instance method." + +// In this case, the delegate has one more +// argument than the instance method this argument comes +// at the beginning, and represents the hidden instance +// argument of the instance method. Use delegate type D1 +// with instance method M1. +let d1 = Delegate.CreateDelegate(typeof, null, mi1) :?> D1 + +// An instance of C must be passed in each time the +// delegate is invoked. +d1.Invoke(c1, "Hello, World!") +d1.Invoke(C 5280, "Hi, Mom!") + +printfn "\nAn open static method." +// In this case, the delegate and the method must +// have the same list of argument types use delegate type +// D2 with static method M2. +let d2 = Delegate.CreateDelegate(typeof, null, mi2) :?> D2 + +// No instances of C are involved, because this is a static +// method. +d2.Invoke "Hello, World!" +d2.Invoke "Hi, Mom!" + +printfn "\nA static method closed over the first argument (String)." +// The delegate must omit the first argument of the method. +// A string is passed as the firstArgument parameter, and +// the delegate is bound to this string. Use delegate type +// D3 with static method M2. +let d3 = Delegate.CreateDelegate(typeof, "Hello, World!", mi2) :?> D3 + +// Each time the delegate is invoked, the same string is used. +d3.Invoke() + +// This code example produces the following output: +// An instance method closed over C. +// Instance method M1 on C: id = 42, s = Hello, World! +// Instance method M1 on C: id = 42, s = Hi, Mom! +// +// An open instance method. +// Instance method M1 on C: id = 42, s = Hello, World! +// Instance method M1 on C: id = 5280, s = Hi, Mom! +// +// An open static method. +// Static method M2 on C: s = Hello, World! +// Static method M2 on C: s = Hi, Mom! +// +// A static method closed over the first argument (String). +// Static method M2 on C: s = Hello, World! +// \ No newline at end of file diff --git a/samples/snippets/fsharp/System/Delegate/CreateDelegate/source.fs b/samples/snippets/fsharp/System/Delegate/CreateDelegate/source.fs new file mode 100644 index 00000000000..529381000b4 --- /dev/null +++ b/samples/snippets/fsharp/System/Delegate/CreateDelegate/source.fs @@ -0,0 +1,126 @@ +module source + +// Showing all the things D(A) can bind to. +// +open System + +// Declare two sample classes, C and F. Class C has an ID +// property so instances can be identified. +type C(id) = + member _.ID = id + + member _.M1(c: C) = + printfn $"Instance method M1(C c) on C: this.id = {id}, c.ID = {c.ID}" + + member _.M2() = + printfn $"Instance method M2() on C: this.id = {id}" + + static member M3(c: C) = + printfn $"Static method M3(C c) on C: c.ID = {c.ID}" + + static member M4(c1: C, c2: C) = + printfn $"Static method M4(C c1, C c2) on C: c1.ID = {c1.ID}, c2.ID = {c2.ID}" + +// Declare a delegate type. The object of this code example +// is to show all the methods this delegate can bind to. +type D = delegate of C -> unit + + +type F() = + member _.M1(c: C) = + printfn $"Instance method M1(C c) on F: c.ID = {c.ID}" + + member _.M3(c: C) = + printfn $"Static method M3(C c) on F: c.ID = {c.ID}" + + member _.M4(f: F, c: C) = + printfn $"Static method M4(F f, C c) on F: c.ID = {c.ID}" + +[] +let main _ = + let c1 = C 42 + let c2 = C 1491 + let f1 = F() + + // Instance method with one argument of type C. + let cmi1 = typeof.GetMethod "M1" + // Instance method with no arguments. + let cmi2 = typeof.GetMethod "M2" + // Static method with one argument of type C. + let cmi3 = typeof.GetMethod "M3" + // Static method with two arguments of type C. + let cmi4 = typeof.GetMethod "M4" + + // Instance method with one argument of type C. + let fmi1 = typeof.GetMethod "M1" + // Static method with one argument of type C. + let fmi3 = typeof.GetMethod "M3" + // Static method with an argument of type F and an argument + // of type C. + let fmi4 = typeof.GetMethod "M4" + + printfn "\nAn instance method on any type, with an argument of type C." + // D can represent any instance method that exactly matches its + // signature. Methods on C and F are shown here. + let d = Delegate.CreateDelegate(typeof, c1, cmi1) :?> D + d.Invoke c2 + let d = Delegate.CreateDelegate(typeof, f1, fmi1) :?> D + d.Invoke c2 + + Console.WriteLine("\nAn instance method on C with no arguments.") + // D can represent an instance method on C that has no arguments + // in this case, the argument of D represents the hidden first + // argument of any instance method. The delegate acts like a + // static method, and an instance of C must be passed each time + // it is invoked. + let d = Delegate.CreateDelegate(typeof, null, cmi2) :?> D + d.Invoke c1 + + printfn "\nA static method on any type, with an argument of type C." + // D can represent any static method with the same signature. + // Methods on F and C are shown here. + let d = Delegate.CreateDelegate(typeof, null, cmi3) :?> D + d.Invoke c1 + let d = Delegate.CreateDelegate(typeof, null, fmi3) :?> D + d.Invoke c1 + + printfn "\nA static method on any type, with an argument of" + printfn " that type and an argument of type C." + // D can represent any static method with one argument of the + // type the method belongs and a second argument of type C. + // In this case, the method is closed over the instance of + // supplied for the its first argument, and acts like an instance + // method. Methods on F and C are shown here. + let d = Delegate.CreateDelegate(typeof, c1, cmi4) :?> D + d.Invoke c2 + let test = + Delegate.CreateDelegate(typeof, f1, fmi4, false) + + // This final example specifies false for throwOnBindFailure + // in the call to CreateDelegate, so the variable 'test' + // contains Nothing if the method fails to bind (for + // example, if fmi4 happened to represent a method of + // some class other than F). + match test with + | :? D as d -> + d.Invoke c2 + | _ -> () + 0 + +// This code example produces the following output: +// An instance method on any type, with an argument of type C. +// Instance method M1(C c) on C: this.id = 42, c.ID = 1491 +// Instance method M1(C c) on F: c.ID = 1491 +// +// An instance method on C with no arguments. +// Instance method M2() on C: this.id = 42 +// +// A static method on any type, with an argument of type C. +// Static method M3(C c) on C: c.ID = 42 +// Static method M3(C c) on F: c.ID = 42 +// +// A static method on any type, with an argument of +// that type and an argument of type C. +// Static method M4(C c1, C c2) on C: c1.ID = 42, c2.ID = 1491 +// Static method M4(F f, C c) on F: c.ID = 1491 +// \ No newline at end of file diff --git a/samples/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs b/samples/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs new file mode 100644 index 00000000000..fc02c8ebe28 --- /dev/null +++ b/samples/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs @@ -0,0 +1,45 @@ +module source1 + +// +open System +open System.Reflection + +// Define two classes to use in the demonstration, a base class and +// a class that derives from it. +type Base() = class end + +type Derived() = + inherit Base() + + // Define a static method to use in the demonstration. The method + // takes an instance of Base and returns an instance of Derived. + // For the purposes of the demonstration, it is not necessary for + // the method to do anything useful. + static member MyMethod(arg: Base) = + Derived() + +// Define a delegate that takes an instance of Derived and returns an +// instance of Base. +type Example = delegate of Derived -> Base + +// The binding flags needed to retrieve MyMethod. +let flags = BindingFlags.Public ||| BindingFlags.Static + +// Get a MethodInfo that represents MyMethod. +let minfo = typeof.GetMethod("MyMethod", flags) + +// Demonstrate contravariance of parameter types and covariance +// of return types by using the delegate Example to represent +// MyMethod. The delegate binds to the method because the +// parameter of the delegate is more restrictive than the +// parameter of the method (that is, the delegate accepts an +// instance of Derived, which can always be safely passed to +// a parameter of type Base), and the return type of MyMethod +// is more restrictive than the return type of Example (that +// is, the method returns an instance of Derived, which can +// always be safely cast to type Base). +let ex = Delegate.CreateDelegate(typeof, minfo) :?> Example + +// Execute MyMethod using the delegate Example. +let b = Derived() |> ex.Invoke +// \ No newline at end of file diff --git a/samples/snippets/fsharp/System/Delegate/Overview/fs.fsproj b/samples/snippets/fsharp/System/Delegate/Overview/fs.fsproj new file mode 100644 index 00000000000..fbff4133403 --- /dev/null +++ b/samples/snippets/fsharp/System/Delegate/Overview/fs.fsproj @@ -0,0 +1,9 @@ + + + Exe + net6.0 + + + + + \ No newline at end of file diff --git a/samples/snippets/fsharp/System/Delegate/Overview/source.fs b/samples/snippets/fsharp/System/Delegate/Overview/source.fs new file mode 100644 index 00000000000..77606cd806f --- /dev/null +++ b/samples/snippets/fsharp/System/Delegate/Overview/source.fs @@ -0,0 +1,35 @@ +// +// Declares a delegate for a method that takes in an int and returns a string. +type MyMethodDelegate = delegate of int -> string + +// Defines some methods to which the delegate can point. +type MySampleClass() = + // Defines an instance method. + member _.MyStringMethod(myInt) = + if myInt > 0 then "positive" + elif myInt < 0 then "negative" + else "zero" + + // Defines a static method. + static member MySignMethod(myInt) = + if myInt > 0 then "+" + elif myInt < 0 then "-" + else "" + +// Creates one delegate for each method. For the instance method, an +// instance (mySC) must be supplied. For the static method, use the +// class name. +let mySC = MySampleClass() +let myD1 = MyMethodDelegate mySC.MyStringMethod +let myD2 = MyMethodDelegate MySampleClass.MySignMethod + +// Invokes the delegates. +printfn $"{5} is {myD1.Invoke 5} use the sign \"{myD2.Invoke 5}\"." +printfn $"{-3} is {myD1.Invoke -3} use the sign \"{myD2.Invoke -3}\"." +printfn $"{0} is {myD1.Invoke 0} use the sign \"{myD2.Invoke 0}\"." + +// This code produces the following output: +// 5 is positive use the sign "+". +// -3 is negative use the sign "-". +// 0 is zero use the sign "". +// \ No newline at end of file diff --git a/samples/snippets/fsharp/VS_Snippets_CLR_System/System.Delegate.GetInvocationList/fs/GetInvocationList1.fs b/samples/snippets/fsharp/VS_Snippets_CLR_System/System.Delegate.GetInvocationList/fs/GetInvocationList1.fs new file mode 100644 index 00000000000..acb899de4eb --- /dev/null +++ b/samples/snippets/fsharp/VS_Snippets_CLR_System/System.Delegate.GetInvocationList/fs/GetInvocationList1.fs @@ -0,0 +1,43 @@ +// +open System +open System.IO +open System.Reflection +open System.Windows.Forms + +let outputToFile (s: string) = + use sw = new StreamWriter(@".\output.txt") + sw.WriteLine s + +let showMessageBox s = + MessageBox.Show s |> ignore + +let outputMessage = + Delegate.Combine( + Action(Console.WriteLine), + Action(outputToFile), + Action(showMessageBox)) + :?> Action + +printfn $"Invocation list has {outputMessage.GetInvocationList().Length} methods." + +// Invoke delegates normally. +outputMessage.Invoke "Hello there!" +printfn "Press to continue..." +stdin.ReadLine() |> ignore + +// Invoke each delegate in the invocation list in reverse order. +for i = outputMessage.GetInvocationList().Length - 1 downto 0 do + let outputMsg = outputMessage.GetInvocationList()[i] + outputMsg.DynamicInvoke "Greetings and salutations!" + |> ignore + +printfn "Press to continue..." +stdin.ReadLine() |> ignore + +// Invoke each delegate that doesn't write to a file. +for i = 0 to outputMessage.GetInvocationList().Length - 1 do + let outputMsg = outputMessage.GetInvocationList()[i] + if not (outputMsg.GetMethodInfo().Name.Contains "File") then + outputMsg.DynamicInvoke "Hi!" + |> ignore +// \ No newline at end of file diff --git a/samples/snippets/fsharp/VS_Snippets_CLR_System/System.Delegate.GetInvocationList/fs/fs.fsproj b/samples/snippets/fsharp/VS_Snippets_CLR_System/System.Delegate.GetInvocationList/fs/fs.fsproj new file mode 100644 index 00000000000..3bc0d99c14e --- /dev/null +++ b/samples/snippets/fsharp/VS_Snippets_CLR_System/System.Delegate.GetInvocationList/fs/fs.fsproj @@ -0,0 +1,10 @@ + + + Exe + net6.0-windows + true + + + + + \ No newline at end of file diff --git a/xml/System/Delegate.xml b/xml/System/Delegate.xml index ec32b6196d6..dbd62a1dc32 100644 --- a/xml/System/Delegate.xml +++ b/xml/System/Delegate.xml @@ -127,6 +127,7 @@ :::code language="cpp" source="~/samples/snippets/cpp/VS_Snippets_CLR_Classic/classic Delegate Example/CPP/source.cpp" id="Snippet1"::: :::code language="csharp" source="~/samples/snippets/csharp/System/Delegate/Overview/source.cs" interactive="try-dotnet" id="Snippet1"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/System/Delegate/Overview/source.fs" id="Snippet1"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_Classic/classic Delegate Example/VB/source.vb" id="Snippet1"::: ]]> @@ -658,6 +659,7 @@ - A delegate of type `D2`, representing an open static method, is created for the static method `M2`. :::code language="csharp" source="~/samples/snippets/csharp/System/Delegate/CreateDelegate/openClosedOver.cs" interactive="try-dotnet" id="Snippet1"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs" id="Snippet1"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR/Delegate.CreateDelegateTOM/VB/openClosedOver.vb" id="Snippet1"::: **Example 2** @@ -676,6 +678,7 @@ :::code language="cpp" source="~/samples/snippets/cpp/VS_Snippets_CLR/Delegate.CreateDelegate_RelaxedFit/cpp/source.cpp" id="Snippet1"::: :::code language="csharp" source="~/samples/snippets/csharp/System/Delegate/CreateDelegate/source1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs" id="Snippet1"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR/Delegate.CreateDelegate_RelaxedFit/vb/source.vb" id="Snippet1"::: ]]> @@ -841,6 +844,7 @@ - Finally, a delegate of type `D3`, closed over a string, is created for the static method `M2`. The method is invoked to show that it uses the bound string. :::code language="csharp" source="~/samples/snippets/csharp/System/Delegate/CreateDelegate/openClosedOver.cs" interactive="try-dotnet" id="Snippet1"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs" id="Snippet1"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR/Delegate.CreateDelegateTOM/VB/openClosedOver.vb" id="Snippet1"::: **Example 2** @@ -862,6 +866,7 @@ :::code language="cpp" source="~/samples/snippets/cpp/VS_Snippets_CLR/Delegate.CreateDelegate_RelaxedFit/cpp/source.cpp" id="Snippet1"::: :::code language="csharp" source="~/samples/snippets/csharp/System/Delegate/CreateDelegate/source1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs" id="Snippet1"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR/Delegate.CreateDelegate_RelaxedFit/vb/source.vb" id="Snippet1"::: **Example 3** @@ -884,6 +889,7 @@ - Finally, delegates are created for static method `M4` of type `C` and type `F`; each method has the declaring type as its first argument, and an instance of the type is supplied, so the delegates are closed over their first arguments. Method `M4` of type `C` displays the `ID` properties of the bound instance and of the argument. :::code language="csharp" source="~/samples/snippets/csharp/System/Delegate/CreateDelegate/source.cs" interactive="try-dotnet" id="Snippet1"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/System/Delegate/CreateDelegate/source.fs" id="Snippet1"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR/Delegate.CreateDelegateTOM_2/vb/source.vb" id="Snippet1"::: ]]> @@ -1109,6 +1115,7 @@ - A delegate of type `D2`, representing an open static method, is created for the static method `M2`. :::code language="csharp" source="~/samples/snippets/csharp/System/Delegate/CreateDelegate/openClosedOver.cs" interactive="try-dotnet" id="Snippet1"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs" id="Snippet1"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR/Delegate.CreateDelegateTOM/VB/openClosedOver.vb" id="Snippet1"::: **Example 2** @@ -1130,6 +1137,7 @@ :::code language="cpp" source="~/samples/snippets/cpp/VS_Snippets_CLR/Delegate.CreateDelegate_RelaxedFit/cpp/source.cpp" id="Snippet1"::: :::code language="csharp" source="~/samples/snippets/csharp/System/Delegate/CreateDelegate/source1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs" id="Snippet1"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR/Delegate.CreateDelegate_RelaxedFit/vb/source.vb" id="Snippet1"::: ]]> @@ -1403,6 +1411,7 @@ - Finally, a delegate of type `D3`, closed over a string, is created for the static method `M2`. The method is invoked to show that it uses the bound string. :::code language="csharp" source="~/samples/snippets/csharp/System/Delegate/CreateDelegate/openClosedOver.cs" interactive="try-dotnet" id="Snippet1"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/System/Delegate/CreateDelegate/openClosedOver.fs" id="Snippet1"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR/Delegate.CreateDelegateTOM/VB/openClosedOver.vb" id="Snippet1"::: **Example 2** @@ -1424,6 +1433,7 @@ :::code language="cpp" source="~/samples/snippets/cpp/VS_Snippets_CLR/Delegate.CreateDelegate_RelaxedFit/cpp/source.cpp" id="Snippet1"::: :::code language="csharp" source="~/samples/snippets/csharp/System/Delegate/CreateDelegate/source1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/System/Delegate/CreateDelegate/source1.fs" id="Snippet1"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR/Delegate.CreateDelegate_RelaxedFit/vb/source.vb" id="Snippet1"::: **Example 3** @@ -1446,6 +1456,7 @@ - Finally, delegates are created for static method `M4` of type `C` and type `F`; each method has the declaring type as its first argument, and an instance of the type is supplied, so the delegates are closed over their first arguments. Method `M4` of type `C` displays the `ID` properties of the bound instance and of the argument. :::code language="csharp" source="~/samples/snippets/csharp/System/Delegate/CreateDelegate/source.cs" interactive="try-dotnet" id="Snippet1"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/System/Delegate/CreateDelegate/source.fs" id="Snippet1"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR/Delegate.CreateDelegateTOM_2/vb/source.vb" id="Snippet1"::: ]]> @@ -2227,6 +2238,7 @@ The following example assigns three methods to a delegate. It then calls the method to get a total count of the methods assigned to the delegate, to execute the delegates in reverse order, and to execute the methods whose name do not include the substring "File". :::code language="csharp" source="~/samples/snippets/csharp/VS_Snippets_CLR_System/System.Delegate.GetInvocationList/cs/GetInvocationList1.cs" id="Snippet1"::: + :::code language="fsharp" source="~/samples/snippets/fsharp/VS_Snippets_CLR_System/System.Delegate.GetInvocationList/fs/GetInvocationList1.fs" id="Snippet1"::: :::code language="vb" source="~/samples/snippets/visualbasic/VS_Snippets_CLR_System/System.Delegate.GetInvocationList/vb/GetInvocationList1.vb" id="Snippet1"::: ]]>