Advertisement

C# Workshop - Week 1 (Ch. 1 & 2) - Advanced

Started by July 01, 2007 12:15 AM
337 comments, last by paulecoyote 17 years, 2 months ago
Quote: Original post by StinkyMarker
Quote: Original post by Vyper_uk
Firstly, if the method is designed to create an object which has computationally expensive creation logic, you might not want to do that logic twice like you would need to using a ref (though in this situation you probably shouldn't be using either ref or out anyway, just a standard method return would do. A simple dummy constructor which does no logic could also be a work around)
[/observation]



when an object is passed by ref, isn't it sent as a pointer and wouldn't be recreated inside the function?


Yes what you are saying is right, I think you misunderstood my example which was along the lines of a method which creates an object with a lot of overhead, eg

private void MakeComplexObject(ref ComplexObject obj) {     obj = new ComplexObject();}



My reasoning was that you would be creating the object twice, once as a 'dummy' to pass using the ref, and again as the 'real' object within the method. However as Sam rightly pointed out, you could just pass in a null object instead to avoid making the object twice
Vyper_uk

ah, I see what you were talking about - makes sense now.
Advertisement
Could someone tell me how to input command line arguments in with Visual C# EE? Also, in the reading they are able to compile programs from the command line using csc, how do I set that up so that I can do that too? Thanks.
Regarding "ref" vs. "out". Neither is better or worse than the other, and neither should be used all the time. They are opposite sides of the same coin. They each serve unique purposes, and when used appropriately are very powerful.

"ref" is used when you want to pass-by-reference a type which is normally pass-by-value, such as a struct. By doing a pass-by-reference it prevents a copy from being made, thus being more efficient. At the same time, it DOES allow the reference being passed in to be modified.

Use "ref" whenever you need to pass something IN to a method for use by the method. Note, the compiler enforces the idea that 'ref' values are used for this purpose by throwing a compile error if the value has not been initialized before being passed to the method.

On the other hand there is the 'out' keyword. This identifies a parameter as being OUTgoing and is going to be used by the caller. This is useful for factories or other design patterns in which an object is created and then returned to the caller. Again, 'out' like 'ref' is most useful when dealing with types, such as structs, which are normally pass-by-value.

To ensure that programmers are using the 'out' keyword correctly, the compiler will throw an error if the value of an out variable is not set within the method.

So to summerize:

Use "ref" if you're setting the value outside of the method, and need it passed-by-reference into a method. Keep in mind that this does allow the method to change the value of the parameter.

Use "out" if you're creating/setting the value inside of the method, and need it passed-by-reference out of the method. Keep in mind that any "out" parameter you pass into the method WILL be written over as a requirement of the "out" keyword.

Finally, "ref" and "out" must be written not only in the method's signature, but also by the calling function. This provides clarity as to the variable's purpose, and helps with readability and maintenance.

Cheers!
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
Before I get flamed I suppose I should follow up and say that yes, 'ref' and 'out' are useful for reference types as well, such as classes.

Although objects are "pass-by-reference" it is a COPY of the reference which is passed in. So although it does allow you to modify the Properties of the object, it does NOT allow you to reallocate. In other words, you cant change the memory address of the variable passed in, even if it's passed by reference. In these cases, 'ref' and 'out' are just as useful with classes and other reference types.

Everything I said above applies to reference types as well, in the case you're trying to reallocate.

Cheers!
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
Quote: Original post by SamLowry
Or use null? Of course, value types can't be null-ed, but then again, they always have default constructors, which shouldn't be too expensive.


I only read the first couple of chapters, but 1.6.6.1 states, "If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided".

Would this mean that if you don't supply an empty constructor it creates one, or does it mean that ONLY if you don't create an instance constructor will it create a default empty one automatically?

class Foo{  Foo(int x);  // Instance constructor};Foo myFoo = new Foo();  // Is this legal?


I'd try this myself, but I'm at work right now and don't have access to a compiler here.
Advertisement
Quote: Original post by JesusMcJesus
Could someone tell me how to input command line arguments in with Visual C# EE?


Not sure if you can specify the params in the UI, but after compiling your app there should be a binary in <project>/bin/Release which you can run from the command line and specify args as you would a program from any other language.


Quote:
Would this mean that if you don't supply an empty constructor it creates one, or does it mean that ONLY if you don't create an instance constructor will it create a default empty one automatically?


As the line you quoted said, if you do not specify any instance constructors then a default one will be created.
Quote: Original post by hpjchobbes
Quote: Original post by SamLowry
Or use null? Of course, value types can't be null-ed, but then again, they always have default constructors, which shouldn't be too expensive.


I only read the first couple of chapters, but 1.6.6.1 states, "If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided".

Would this mean that if you don't supply an empty constructor it creates one, or does it mean that ONLY if you don't create an instance constructor will it create a default empty one automatically?

*** Source Snippet Removed ***

I'd try this myself, but I'm at work right now and don't have access to a compiler here.


The default constructor for classes is only created for you if you yourself specify no constructors at all.


Default constructor stuff summarized:

  • Classes: only if you define no constructors yourself, a default one will be provided automatically. This one will initialize all fields to their respective defaults (0 for numeric values, default constructor will be called for structs, null for references). See 10.10.4.

  • Structs: always have a default constructor which initializes all fields to their respective defaults. You can't specify you own parameterless constructor. See 4.1.2.



[Edited by - SamLowry on July 2, 2007 1:34:46 PM]
Quote: Original post by SamLowry
Quote: Original post by hpjchobbes
Would this mean that if you don't supply an empty constructor it creates one, or does it mean that ONLY if you don't create an instance constructor will it create a default empty one automatically?

I'd try this myself, but I'm at work right now and don't have access to a compiler here.


The default constructor is only created for you if you yourself specify no constructors at all.


If I understood everything well, it is provided for all structs you create, even if you create a non-default constructor (and you don't have the right to create a default constructor for structs anyway).

I'm going to read more about classes this evening. Hopefully, I'll get something clear in my head (not that it's difficult - I can cope with that...).

Cheers!
Quote: Original post by Emmanuel Deloget
If I understood everything well, it is provided for all structs you create, even if you create a non-default constructor (and you don't have the right to create a default constructor for structs anyway).


That is correct. I was answering in the context of classes only. I have updated my post to prevent confusion.

This topic is closed to new replies.

Advertisement