Return an (Anonymous Type with a Function) from a Function - Is There a Better Way?
Just so it's known, this question is mostly academic, even though I tried to use the concept in a real-world solution. I realize the example is contrived, but I believe the concept is valid.
I want to write some fluent code like this:
copy(my_first_file).to(my_second_file)
Short, easy to read and understand, perfectly legit. So I define my copy method like this:
Private Function copy(FilePath as String) As Object
Return New With {.to = New Action(Of String)(Function(x) my_real_copy_method(FilePath,x))}
End Function
I realize that I can't force an anonymous type into a specific type (like implementing an interface or some other class), and I don't want the overhead of defining a specific class just to match my desired fluent name with the actual method name. So I was able to make the code work like this:
copy(my_first_file).to.Invoke(my_second_file)
So there is no IntelliSense or type awareness there, and I have to include the Invoke in order to have t开发者_StackOverflow社区he method run. How can I get more type safety and exclude the Invoke method, under these constraints:
- Anonymous Type returned from Method
- No additional classes or interfaces
- Preferably, I do not want to pass in another parameter to the copy() method that tells what type to return, unless copy becomes a generic method (but I think that means defining another class/interface, which I don't want to do)
I know that sounds pretty demanding, feel free to call "Bull" if I'm being to difficult!
Thanks in advance.
Since VB has no return type inference for generic methods, even where there is no ambiguity, there is no way of doing this.
You can have a strongly typed function that returns an anonymous type using generics but you cannot call it with inferred generics, you need to specify them explicitly.
Private Function Copy(Of T)(filePath as String, prototype As T) As T
Return New With { .To = … }
End Function
(Naming convention adapted to .NET)
This must be called as follows:
Dim nullAction As Action(Of String) = Nothing
Dim proto = New With { .To = nullAction }
Copy(firstFile, proto).To(secondFile)
I'm sorry; this is the best I could come up with. It doesn't meet your requirements....but it does give you the syntax you wanted.
Sub Main()
copy("myFile").To("myOtherFile")
End Sub
Private Function copy(ByVal FilePath As String) As String
Return FilePath
End Function
<Extension()> _
Public Sub [To](ByVal FromFile As String, ByVal ToFile As String)
' Code to really copy goes here
my_real_copy_method(FromFile, ToFile)
End Sub
I know you said your example is contrived, but how about this? It supports method chaining (CopyTo
returns a FileInfo
), even if it's not fluent. It's built into System.IO
too.
Dim f As New FileInfo("c:\x.txt")
f.CopyTo("c:\y.txt")
精彩评论