2

I'm new to F# and was just wondering how to write the below C# code in F#?

// Issue request and remember to dispose of the response
using (GetObjectResponse response = client.GetObject(request))
{
    using (StreamReader reader = new StreamReader(response.ResponseStream))
    {
        string contents = reader.ReadToEnd();
        Console.WriteLine("Object - " + response.Key);
        Console.WriteLine(" Version Id - " + response.VersionId);
        Console.WriteLine(" Contents - " + contents);
    }
}

I have read up on the documentation using use and came up with this:

    use response = s3Client.GetObject(req)
    (
      use reader = new StreamReader(response.ResponseStream)
      urlCheck = reader.ReadToEnd())
      Console.WriteLine(urlCheck)

but it's not working at all. Could anybody help?

EDIT
I used this link: f# keyword use and using as a template for my solution above but it didn't work.

The error I get is that "reader is not a function and cannot be applied".

Also, I know I could just leave it in C#, but I'd like to see if I can port it over to F#. Any advice on this would be much appreciated.

Community
  • 1
  • 1
xn139
  • 375
  • 1
  • 4
  • 16
  • nothing wrong with mixing languages, perhaps just leave it in C# – Brian Ogden Mar 19 '17 at 19:00
  • "not working" is generally a poor way to describe your problem - what happens? Do you get an error? (If so, give us the error). Do you get an unexpected response (If so, describe the expectations and the actual outcome) – Damien_The_Unbeliever Mar 19 '17 at 19:02
  • I've made edits above. – xn139 Mar 19 '17 at 19:12
  • That line with urlCheck = reader.ReadToEnd(), perhaps you meant "let urlCheck = ...", since the way it is now it becomes a boolean test. – Bent Tranberg Mar 19 '17 at 19:28
  • In F# we hardly ever indent "use" with parenthesis like that. The gain is infinitesimal, and it's not worth sacrificing readability over. – Bent Tranberg Mar 19 '17 at 19:32
  • ... in almost all cases. There are exceptions where you want disposal to happen sooner, and that's when you control the scope with parenthesis. – Bent Tranberg Mar 19 '17 at 19:44
  • Hi Bent, many thanks for this - I'll stop using the () now. Your suggestion has resolved some of the problems - however, when I print the contents of the urlCheck - the encoding comes out all wrong and I'm not too sure why. What should be printed: {AmazonId2 = ContentLength = 1138630L; ... } However, I get 'gibberish' back. Is this more of an AWS thing or an F# thing? – xn139 Mar 19 '17 at 19:45

1 Answers1

3

The use keyword in F# has slightly different mechanics than the C#'s using. One major difference is that in C# you explicitly specify the scope of the using with curly braces, but the F#'s use affects the whole "current block" (let-binding or member), from the use to the end. So that you don't have to explicitly "nest" (i.e. indent) the code that is "under" the use. Just keep on writing as usual:

use response = s3Client.GetObject(req)
use reader = new StreamReader(response.ResponseStream)
let urlCheck = reader.ReadToEnd()
Console.WriteLine(urlCheck)
Fyodor Soikin
  • 78,590
  • 9
  • 125
  • 172
  • Hi Fyodor, many thanks for this - it's resolved some of the problems - however, when I print the contents of the urlCheck - the encoding comes out all wrong and I'm not too sure why. What should be printed: {AmazonId2 = ContentLength = 1138630L; ... } However, I get 'gibberish' back. Is this more of an AWS thing or an F# thing? – xn139 Mar 19 '17 at 19:43
  • Well looking at the C# equivalent, it doesn't seem like it needs any other special encoding than what is there by default - that's what's weird! – xn139 Mar 19 '17 at 20:25
  • A long shot: In the C# version, response is declared as GetObjectResponse. Is it possible that s3Client.GetObject(req) does not return that compile time type? I am thinking perhaps response then gets the wrong compile time type, and then this again can affect which response.ResponseStream is called in the next line. Verify the inferred type of response is indeed GetObjectResponse. – Bent Tranberg Mar 19 '17 at 20:44
  • You are typing the output to the console. That might prevent you from seeing interesting stuff in the string. As for the encoding, don't trust the default to be the same as in C#, so do try setting other encodings explicitly. – Bent Tranberg Mar 19 '17 at 21:07
  • @BentTranberg tried everything you said - it is a type of GetObjectResponse. Also tried changing the encoding - just not working! Will have more of a play around with it! Thanks for your help. – xn139 Mar 19 '17 at 21:59
  • Are you saying that the C# version prints something legible, but F# version prints garbage? With the same inputs? – Fyodor Soikin Mar 19 '17 at 22:25