Conversation started Jul 18, 2016 at 21:09.
Jul 18, 2016 21:09
someone ping me when @ExtremeCSharper comes in
thanks
care to join me in The Second Monitor and help me to understand why you don't like my suggestion? I am open to learning more about C# than I already do. thank you — Malachi 29 secs ago
(if you need help giving explicit write access let me know)
@Malachi I'm pretty sure he is right, that you should leave the using statement, and then return, to properly call Dispose() on the value.
Also, your guest is here.
Hi, @extremecsharper.
Update: Both I and he is wrong: stackoverflow.com/questions/11776945/…
> It's perfectly safe to call return inside your using block, since a using block is just a try/finally block.
@extremecsharper it's not so much that it is faster, I haven't tested it.
like @Hosch250 and that SO answer said, the dispose is essentially inside of a finally block, it wouldn't make sense to return after the finally block, it would make more sense to return inside the block itself.
I also thought about moving the instantiation of the variable inside of the using statement as well, because there was no reason to declare it outside of the statement, it should be declared just outside of the foreach loop
@Malachi Wrong analogy.
yeah probably
Jul 18, 2016 21:24
I'm not too sure how try/finally's work, but if you don't dispose correctly, you'll have a memory leak.
the purpose of the using statement is to avoid the "if you don't dispose correctly"
the data isn't linked to the things being disposed of in that code
I mean, I'm not sure where the finally runs.
after scope leaves the using block
Does it run before the return anyway, or after?
I am pretty sure that the finally would run after the return
	private IEnumerable<ExpandoObject> GetOuGroupsUsersData(
		PrincipalContext pc)
	{
		var data = new List<ExpandoObject>();
		try {
			var gp = new GroupPrincipal(pc);
			var ps = new PrincipalSearcher(gp);
			var psr = ps.FindAll();
			foreach (var g in psr.GetGroupPrincipals())
			{
				try {
					var gpsr = g.GetMembers();
					data.AddRange(
						gpsr.GetUserPrincipals().Select(
							u => GenerateData(g, u))
							.Cast<ExpandoObject>());
				}
				finally{
					gpsr.Dispose();
				}
			}
that is what it would look like if you didn't use the using blocks
so of course you would put the return inside the try block before the final finally but after the foreach. the finally statements are just clean up
there is the possibility that a return can error, so I would assume that the return would fire before the finally block cleans up
Jul 18, 2016 21:33
Yeah, it does.
From what I can figure out, it leaves the scope, loads the value into a variable, then runs the finally.
@Hosch250 are you saying that it returns then disposes?
Yeah.
Well, no.
It leaves the scope, calls the finally, then returns from the method.
class Bar
{
    public string Main()
    {
        using (var f = new System.IO.StreamWriter(""))
        {
            return "test";
        }
    }
}
IL_0000:  nop
IL_0001:  ldstr       ""
IL_0006:  newobj      System.IO.StreamWriter..ctor
IL_000B:  stloc.0     // f
IL_000C:  nop
IL_000D:  ldstr       "test"
IL_0012:  stloc.1
IL_0013:  leave.s     IL_0020
IL_0015:  ldloc.0     // f
IL_0016:  brfalse.s   IL_001F
IL_0018:  ldloc.0     // f
IL_0019:  callvirt    System.IDisposable.Dispose
IL_001E:  nop
IL_001F:  endfinally
IL_0020:  ldloc.1
IL_0021:  ret
jrh
jrh
Quick question, do you guys think Bit Endianness is still a big deal these days? PowerPC Macs are pretty old...
IL_0006:  newobj      System.IO.StreamWriter..ctor    // creates StreamWriter
IL_0013:  leave.s     IL_0020    // leaves scope
IL_0019:  callvirt    System.IDisposable.Dispose    // calls dispose
IL_001E:  nop
IL_001F:  endfinally    // finishes finally block
IL_0021:  ret    // returns from method
would it be different if it were multi threaded? random question might not have any bearing
Jul 18, 2016 21:40
I'm pretty sure not.
it still sets the return variable before it calls the Dispose though
> IL_0016: brfalse.s IL_001F
Of course, otherwise it would lose it.
try to return from outside of the using
Can't return a boolean from a string.
It detects unreachable code and doesn't do anything.
I mis-typed
sorry
Jul 18, 2016 21:43
IL_0000:  nop
IL_0001:  ldsfld      System.Boolean.FalseString
IL_0006:  ldstr       "False"
IL_000B:  call        System.String.op_Equality
IL_0010:  stloc.0
IL_0011:  ldloc.0
IL_0012:  brfalse.s   IL_0034
IL_0014:  nop
IL_0015:  ldstr       ""
IL_001A:  newobj      System.IO.StreamWriter..ctor
IL_001F:  stloc.1     // f
IL_0020:  nop
IL_0021:  ldstr       "test"
IL_0026:  stloc.2
IL_0027:  leave.s     IL_003C
IL_0029:  ldloc.1     // f
IL_002A:  brfalse.s   IL_0033
IL_002C:  ldloc.1     // f
IL_002D:  callvirt    System.IDisposable.Dispose
The actual leaving of the method is still the last thing to execute.
Once it leaves the method, it can't run any code from it. The finally will always run before the last brace (if you can say the last brace really runs...)
I asked @Nick_Craver why he sold his house and he said "String allocations in the walls" and I laughed but he didn't https://twitter.com/Nick_Craver/status/754047901949657088
@Hosch250 agreed.
that isn't the same code with the return outside of the using block though, what is the C# code?
class Bar
{
    public string Main()
    {
        if (bool.FalseString == "False")
        {
            using (var f = new System.IO.StreamWriter(""))
            {
                return "test";
            }
        }

        return bool.FalseString;
    }
}
I had to use an if to make it not just compile away the final return.
I gotta finish this email, but this was rather enlightening either way.
remind me to ask you how you get to that compiler code or whatever it is....I haven't ever messed with that, and I would like to
LinqPad.
I have the free version.
Jul 18, 2016 21:54
me too. but you can see that in VS as well can't you?
Possibly, I don't know.
It's called "IL", anyway.
Just go to the IL tab in LinqPad.
jrh
jrh
I'd recommend ildasm if you don't have linqpad
it comes with visual studio
you can access it through the visual studio command prompt
I'll tell you where it is in a few... got to go
 
Conversation ended Jul 18, 2016 at 22:00.