By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,760 Members | 1,585 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,760 IT Pros & Developers. It's quick & easy.

fundamental scope question

P: n/a
I feel like an idiot asking this but here goes: I understand the 'concept'
of scope and passing data by value and/or by reference but I am confused on
some specifics.

class example{
int i; //my global var

private void method1(int myInt){
int x; //local var
etc...
}

private void method2(int myInt){
int z; //local var
etc...
}
}

so I get that the global var i is accessible by any methods in above class
example, based on where its declared, and that the var x, for example, is
local to method1 and only accessible from method1. And beyond that, within a
method, you can have further localized variables within conditional IF
blocks or loops. I get that passing data byval passes a 'copy' of the passed
variable's data and that passing byref passes the actual memory location of
the passed variable. So, for instance, if my global var i was passed byref
to either of those methods in the example and modified, that actual global
var i would be modified directly... whereas if it was passed byval and
modified within the method that the global i var would remain untouched.

now here is where I get confused: say the var x in method1 was a reference
type like 'object'. It is declared in method1, so scope is only method1.
What if method2 was called from method1, and x is passed in. Would the x
used in method2 be the same x from method1? If I wanted it to be would x
have to be declared outside both those methods where my example global var i
is?

side bar question: does c# pass parameters by value or by reference by
default? (i think its by value except I recall something special about
strings?)
May 10 '07 #1
Share this Question
Share on Google+
20 Replies


P: n/a
David,

Well, i isn't global, in the sense that it is scoped to instances of the
class example. Only other members of the class can see i.

Here is an example which should help you understand the difference
between passing references by value, and by reference.

public class MyClass
{
public string Name = null;
}

public void DoSomething(MyClass myClass)
{
// myClass is passed by value. In this case, it is the reference that
is passed by value.
// You can make changes to members of the instance, but not the
reference itself. So the following
// will change the name.
myClass.Name = "Nicholas Paldino";

// However, this will not change what myClass points to. For the rest
of the method though, myClass
// will point to the new instance.
myClass = new MyClass();
}

public void DoSomething2(ref MyClass myClass)
{
// Here, myClass can be changed.
myClass = new MyClass();
}

public void Test()
{
// Create an instance of MyClass.
MyClass mc = new MyClass();

// Set the name.
mc.Name = "David";

// Store a reference for comparison later.
MyClass oldMc = mc;

// Call the first DoSomething method.
DoSomething(mc);

// At this point, mc.Name will be "Nicholas Paldino".
Console.WriteLine("mc.Name: {0}, mc.Name);

// The reference has not changed.
Console.WriteLine("mc == oldMc: {0}", Object.ReferenceEquals(mc,
oldMc));

// Now call DoSomething2.
DoSomething2(ref mc);

// The references are not the same.
Console.WriteLine("mc == oldMc after call to DoSomething2: {0}",
Object.ReferenceEquals(mc, oldMc));
}

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"David" <no****@nospam.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
>I feel like an idiot asking this but here goes: I understand the 'concept'
of scope and passing data by value and/or by reference but I am confused on
some specifics.

class example{
int i; //my global var

private void method1(int myInt){
int x; //local var
etc...
}

private void method2(int myInt){
int z; //local var
etc...
}
}

so I get that the global var i is accessible by any methods in above class
example, based on where its declared, and that the var x, for example, is
local to method1 and only accessible from method1. And beyond that, within
a method, you can have further localized variables within conditional IF
blocks or loops. I get that passing data byval passes a 'copy' of the
passed variable's data and that passing byref passes the actual memory
location of the passed variable. So, for instance, if my global var i was
passed byref to either of those methods in the example and modified, that
actual global var i would be modified directly... whereas if it was passed
byval and modified within the method that the global i var would remain
untouched.

now here is where I get confused: say the var x in method1 was a reference
type like 'object'. It is declared in method1, so scope is only method1.
What if method2 was called from method1, and x is passed in. Would the x
used in method2 be the same x from method1? If I wanted it to be would x
have to be declared outside both those methods where my example global var
i is?

side bar question: does c# pass parameters by value or by reference by
default? (i think its by value except I recall something special about
strings?)


May 10 '07 #2

P: n/a
Pl give a look at the concept of OUT Key word in C# Language Ref.

Dont get confuse with the VB's ByVal and ByRef keywords in C# Language.

For ByRef of VB, all you have do is use OUT key word in C# as mentioned below

int y;
public int DoSome(int x, out int y)
{
y=10; // will send the value out of the scope
x=11; // will distroy the value inside this method
}

HTH
--
Every thing is perfect, as long as you share!!!

Don''t forget to rate the post
"David" wrote:
I feel like an idiot asking this but here goes: I understand the 'concept'
of scope and passing data by value and/or by reference but I am confused on
some specifics.

class example{
int i; //my global var

private void method1(int myInt){
int x; //local var
etc...
}

private void method2(int myInt){
int z; //local var
etc...
}
}

so I get that the global var i is accessible by any methods in above class
example, based on where its declared, and that the var x, for example, is
local to method1 and only accessible from method1. And beyond that, within a
method, you can have further localized variables within conditional IF
blocks or loops. I get that passing data byval passes a 'copy' of the passed
variable's data and that passing byref passes the actual memory location of
the passed variable. So, for instance, if my global var i was passed byref
to either of those methods in the example and modified, that actual global
var i would be modified directly... whereas if it was passed byval and
modified within the method that the global i var would remain untouched.

now here is where I get confused: say the var x in method1 was a reference
type like 'object'. It is declared in method1, so scope is only method1.
What if method2 was called from method1, and x is passed in. Would the x
used in method2 be the same x from method1? If I wanted it to be would x
have to be declared outside both those methods where my example global var i
is?

side bar question: does c# pass parameters by value or by reference by
default? (i think its by value except I recall something special about
strings?)
May 10 '07 #3

P: n/a
On May 10, 7:14 pm, "David" <nos...@nospam.comwrote:
I feel like an idiot asking this but here goes: I understand the 'concept'
of scope and passing data by value and/or by reference but I am confused on
some specifics.

class example{
int i; //my global var

private void method1(int myInt){
int x; //local var
etc...
}

private void method2(int myInt){
int z; //local var
etc...
}

}

so I get that the global var i is accessible by any methods in above class
example, based on where its declared, and that the var x, for example, is
local to method1 and only accessible from method1. And beyond that, within a
method, you can have further localized variables within conditional IF
blocks or loops. I get that passing data byval passes a 'copy' of the passed
variable's data and that passing byref passes the actual memory location of
the passed variable. So, for instance, if my global var i was passed byref
to either of those methods in the example and modified, that actual global
var i would be modified directly... whereas if it was passed byval and
modified within the method that the global i var would remain untouched.

now here is where I get confused: say the var x in method1 was a reference
type like 'object'. It is declared in method1, so scope is only method1.
What if method2 was called from method1, and x is passed in. Would the x
used in method2 be the same x from method1? If I wanted it to be would x
have to be declared outside both those methods where my example global var i
is?

side bar question: does c# pass parameters by value or by reference by
default? (i think its by value except I recall something special about
strings?)
David,

I'll start from the end: All primitive types are passed by value (like
int, decimal etc). string is a special case since it's passed by
reference but is immutable so you can't change it's content, only the
location it points to (you can do s="m").

Since your example functions are getting int parameters, each of the
passed parameter is passed by value.
You can use the 'ref' keyword to pass primitives by reference:
//
void method1(ref int i)
{
++i;
}

Hope this helps.
Moty

May 10 '07 #4

P: n/a
The ref keyword is more like ByRef in VB. AFAIK, out doesn't have a
representation in VB.NET.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Chakravarthy" <ds******@india.comwrote in message
news:CD**********************************@microsof t.com...
Pl give a look at the concept of OUT Key word in C# Language Ref.

Dont get confuse with the VB's ByVal and ByRef keywords in C# Language.

For ByRef of VB, all you have do is use OUT key word in C# as mentioned
below

int y;
public int DoSome(int x, out int y)
{
y=10; // will send the value out of the scope
x=11; // will distroy the value inside this method
}

HTH
--
Every thing is perfect, as long as you share!!!

Don''t forget to rate the post
"David" wrote:
>I feel like an idiot asking this but here goes: I understand the
'concept'
of scope and passing data by value and/or by reference but I am confused
on
some specifics.

class example{
int i; //my global var

private void method1(int myInt){
int x; //local var
etc...
}

private void method2(int myInt){
int z; //local var
etc...
}
}

so I get that the global var i is accessible by any methods in above
class
example, based on where its declared, and that the var x, for example, is
local to method1 and only accessible from method1. And beyond that,
within a
method, you can have further localized variables within conditional IF
blocks or loops. I get that passing data byval passes a 'copy' of the
passed
variable's data and that passing byref passes the actual memory location
of
the passed variable. So, for instance, if my global var i was passed
byref
to either of those methods in the example and modified, that actual
global
var i would be modified directly... whereas if it was passed byval and
modified within the method that the global i var would remain untouched.

now here is where I get confused: say the var x in method1 was a
reference
type like 'object'. It is declared in method1, so scope is only method1.
What if method2 was called from method1, and x is passed in. Would the x
used in method2 be the same x from method1? If I wanted it to be would x
have to be declared outside both those methods where my example global
var i
is?

side bar question: does c# pass parameters by value or by reference by
default? (i think its by value except I recall something special about
strings?)

May 10 '07 #5

P: n/a
Moty Michaely <Mo*****@gmail.comwrote:
I'll start from the end: All primitive types are passed by value (like
int, decimal etc). string is a special case since it's passed by
reference but is immutable so you can't change it's content, only the
location it points to (you can do s="m").
No.

a) String is a reference type to start with
b) String isn't treated differently to any other reference types
c) *All* parameters are passed by value by default

See http://pobox.com/~skeet/csharp/parameters.html
Since your example functions are getting int parameters, each of the
passed parameter is passed by value.
They *are* being passed by value, but the reason is simple: they're not
declared as ref or out.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 10 '07 #6

P: n/a
On Thu, 10 May 2007 09:14:42 -0700, David <no****@nospam.comwrote:
I feel like an idiot asking this but here goes: I understand the
'concept' of scope and passing data by value and/or by reference
but I am confused on some specifics.
I recommend you look at the link Jon offered. He's done a nice write-up
on this question, as it comes up a lot. :)

For your specific questions (they should be answered by Jon's write-up,
but just in case):
now here is where I get confused: say the var x in method1 was a
reference type like 'object'. It is declared in method1, so scope is
only method1.
Keep in mind that "scope" and "lifetime" are not exactly the same thing.
They are often related, but they are two different characteristics of a
variable.

In particular, while you are correct that the scope of x is limited to
method1, and the lifetime of x is only during the time between the entry
to method1 and the exit from method1, this also means that the lifetime of
x includes any calls method1 may make to other methods.
What if method2 was called from method1, and x is passed in. Would thex
used in method2 be the same x from method1?
By default, no. However, if you use "ref" or "out", it would be the same.
If I wanted it to be would x
have to be declared outside both those methods where my example global
var i is?
No, x would not have to be declared "global" (as someone else noted, it's
not really global...it's just outside the methods, but in the class). You
can use "ref" or "out" to have the variable x in method1 actually
manipulated by some other method.

Obviously, this only works for things you pass to the method, since those
keywords only apply to parameters to methods. :)
side bar question: does c# pass parameters by value or by reference by
default? (i think its by value except I recall something special about
strings?)
Strings are not special-cased, but because they are immutable reference
types, they do in some ways behave more like value types than reference
types.

By default passing is always "by value". The "ref" and "out" keywords
cause things to be passed "by reference". Not to be confused with the
difference between "value types" and "reference types". Again, I think
Jon's write-up does a good job of outlining the various combinations of
value and reference types being passed by value and by reference. A quick
summary though:

1) pass value type by value: a copy of the value type is made and
passed to the method
example:
void method1(int x)
{
x = 5;
}
void method2()
{
int y = 4;

method1(y);
Console.WriteLine(y);
}

output:
4

2) pass reference type by value: a copy of the reference is made and
passed to the method, but it's important to note that it's the *reference*
being copied, not the object itself. So unless the reference type is
immutable (like String, for example), the object itself can be modified by
the called method (but the reference to the object cannot be)
example:
class A
{
public int i;

public A(int j)
{
i = j;
}
}
void method1(A x)
{
x.i = 5;
x = new A(6);
}
void method2()
{
A y = new A(4);

method1(y);
Console.WriteLine(y.i);
}

output:
5

3) pass value type by reference: a reference to the value type is
passed, and the called method can modify the original value type instance
example:
void method1(ref int x)
{
x = 5;
}
void method2()
{
int y = 4;

method1(ref y);
Console.WriteLine(y);
}

output:
5

4) pass reference type by reference: a reference to the reference is
made; not only can the reference type object be modifed as in case #2, but
the reference *to* that object can be modified as well.
example:
class A
{
public int i;

public A(int j)
{
i = j;
}
}
void method1(ref A x)
{
x.i = 5;
x = new A(6);
}
void method2()
{
A y = new A(4);

method1(ref y);
Console.WriteLine(y.i);
}

output:
6

Hope that helps.

Pete
May 10 '07 #7

P: n/a
thanks all for the great information. I'm heading to review Jon's page now
for a review of passing parameters. Below is one last question that Peter
provided the perfect setup for:

from Peter:
"Keep in mind that "scope" and "lifetime" are not exactly the same thing.
They are often related, but they are two different characteristics of a
variable.

In particular, while you are correct that the scope of x is limited to
method1, and the lifetime of x is only during the time between the entry
to method1 and the exit from method1, this also means that the lifetime of
x includes any calls method1 may make to other methods."

perfect setup for this question: scope limited to method1, lifetime from
entry to exit of method1, so what if in method1 an asynchronous method2 is
called that takes a variable that was declared in method1 as a parameter
(either a value type by ref, or a reference type by val), method1 exits
since the asnyc method2 does not block, what happens to that parameter since
its lifetime would be over? will method2, which could still be running, be
able to utilize it? does the framework realize this is happening and extend
the life of the var for method2?

I'm going to read Jon's page now... thanks again.

May 10 '07 #8

P: n/a
David <no****@nospam.comwrote:

<snip>
perfect setup for this question: scope limited to method1, lifetime from
entry to exit of method1, so what if in method1 an asynchronous method2 is
called that takes a variable that was declared in method1 as a parameter
(either a value type by ref, or a reference type by val), method1 exits
since the asnyc method2 does not block, what happens to that parameter since
its lifetime would be over?
For a reference type by value, there's no problem at all - the
parameter being passed is just passed by value, i.e. a copy of the
reference is made; the variable itself isn't involved.

For parameters passed by reference, it's a very interesting question
which I hadn't thought of before.

I had to consult the docs, and what happens is that the parameter is
effectively passed by value instead of by reference, but the value at
the end of the asynchronous call is available when you call EndInvoke
instead.

It's nice to learn something new...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 10 '07 #9

P: n/a
On Thu, 10 May 2007 12:56:15 -0700, David <no****@nospam.comwrote:
[...]
perfect setup for this question: scope limited to method1, lifetime from
entry to exit of method1, so what if in method1 an asynchronous method2
is
called that takes a variable that was declared in method1 as a parameter
(either a value type by ref, or a reference type by val), method1 exits
since the asnyc method2 does not block, what happens to that parameter
since its lifetime would be over?
Good question. Certainly, doing that would be a bad thing. It would be
unusual (but not impossible) to set up that scenario in the first place,
but if you did, then indeed if the lifetime of the variable does not span
the time during which method2 executes, the variable would be "gone"
before the method2 tried to use it. That's bad. :)

However, I cobbled up some code (see below) to see what .NET would
actually do, and it didn't complain at all. I have no idea what got set
to "5" in my method2(), but it definitely wasn't the variable "j" in my
method1() (though it might be the storage used by that local
variable...see comments below).

Maybe someone who actually knows can answer that part of the question.
Regardless of what .NET does though, you should not do this.
will method2, which could still be running, be
able to utilize it? does the framework realize this is happening and
extend the life of the var for method2?
As I mention above, I don't know what .NET is actually doing. In my test
code, executing a second method with the same local variables as the first
method doesn't change the value of the ref parameter. From that, I
presume that .NET's garbage collection has actually taken the local
variable, noted that it's still referenced, and the lifetime of the
variable extends outside of the method's lifetime.

Regardless of what .NET is doing, however, I submit that it's probably not
a good idea to pass things by reference unless the calling code is going
to stick around long enough to find out what happened to them. :)

Pete

here's my test code...note the use of waitable events to ensure that each
thread executes the statements in the order I want them to. Real-world
code might or might not have something similar, depending on what it's
actually doing.

class Program
{
static AutoResetEvent are1 = new AutoResetEvent(false);
static AutoResetEvent are2 = new AutoResetEvent(false);

delegate void RefParmHandler(ref int i);

static void method2(ref int i)
{
are1.WaitOne();
i = 5;
are2.Set();
}

static void method1()
{
int j = 4;
RefParmHandler rpf = new RefParmHandler(method2);

rpf.BeginInvoke(ref j, null, null);
}

static void method3()
{
int k = 3;
}

static void Main(string[] args)
{
method1();
method3();
are1.Set();
are2.WaitOne();
}
}
May 10 '07 #10

P: n/a
Peter Duniho <Np*********@nnowslpianmk.comwrote:

<snip>
Maybe someone who actually knows can answer that part of the question.
Regardless of what .NET does though, you should not do this.
Well, the behaviour is well-defined (by the CLI spec). It's very
obscure though - if I found a case where I thought it was really,
really the nicest way of doing things, I'd be putting big scary
comments explaining what was going on. I try to avoid writing "clever"
code which needs explanation.

<snip>
Regardless of what .NET is doing, however, I submit that it's probably not
a good idea to pass things by reference unless the calling code is going
to stick around long enough to find out what happened to them. :)
In this case, other code can still find out what happened using
EndInvoke.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 10 '07 #11

P: n/a
On Thu, 10 May 2007 13:45:18 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
>Maybe someone who actually knows can answer that part of the question.
Regardless of what .NET does though, you should not do this.

Well, the behaviour is well-defined (by the CLI spec). It's very
obscure though - if I found a case where I thought it was really,
really the nicest way of doing things, I'd be putting big scary
comments explaining what was going on. I try to avoid writing "clever"
code which needs explanation.
Yes, I agree that given it's a well-defined behavior (I didn't realize
this when I wrote my previous post), I should back off the absolute
admonishment to not do it. However, I still think it's almost always a
sign of poor design. :) I'd love to see an example of code where it
could be strongly argued that it "was really, really the nicest way of
doing things". I'm having a hard time imagining a place where a "ref"
parameter is clearly superior to using some less-opaque means (like using
a reference type) :)

Pete
May 10 '07 #12

P: n/a
Peter Duniho <Np*********@nnowslpianmk.comwrote:
Well, the behaviour is well-defined (by the CLI spec). It's very
obscure though - if I found a case where I thought it was really,
really the nicest way of doing things, I'd be putting big scary
comments explaining what was going on. I try to avoid writing "clever"
code which needs explanation.

Yes, I agree that given it's a well-defined behavior (I didn't realize
this when I wrote my previous post), I should back off the absolute
admonishment to not do it. However, I still think it's almost always a
sign of poor design. :) I'd love to see an example of code where it
could be strongly argued that it "was really, really the nicest way of
doing things". I'm having a hard time imagining a place where a "ref"
parameter is clearly superior to using some less-opaque means (like using
a reference type) :)
Agreed. One possible example would be where you already *had* the
implementation of what you wanted to do as a method, and needed to use
that implementation as a delegate action. You may not be able to change
the signature of the method (it could be part of an interface
implementation or somesuch). You could create a new method which called
the existing one, admittedly, but that would be irritating too.

I wonder how many people have ever used this? I *hope* it's vanishingly
small.

(Personally I try to avoid out/ref parameters anyway, aside from
TryParse type operations.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 10 '07 #13

P: n/a
David wrote:
now here is where I get confused: say the var x in method1 was a reference
type like 'object'. It is declared in method1, so scope is only method1.
The reference variable has that scope, but the object itself doesn't
have any scope at all.

The reference variable is allocated on the stack and lives as long as
the method is running. The object is allocated on the heap and lives
until garbage collected.
What if method2 was called from method1, and x is passed in. Would the x
used in method2 be the same x from method1?
Yes, the object used would be the same.
If I wanted it to be would x
have to be declared outside both those methods where my example global var i
is?
No. When you pass the reference to another method, that reference
becomes a new local variable in that method, with it's own scope. You
have two reference variables with different scopes that reference the
same object, and as I said the object itself doesn't have any scope at all.

--
Göran Andersson
_____
http://www.guffa.com
May 10 '07 #14

P: n/a
thanks Goran. After reading Peter and Jon's information (including Jon's web
pages) I now realize this. And what you have answered here was exactly my
point of confusion.

thanks again all.
"Göran Andersson" <gu***@guffa.comwrote in message
news:eJ**************@TK2MSFTNGP02.phx.gbl...
David wrote:
>now here is where I get confused: say the var x in method1 was a
reference type like 'object'. It is declared in method1, so scope is only
method1.

The reference variable has that scope, but the object itself doesn't have
any scope at all.

The reference variable is allocated on the stack and lives as long as the
method is running. The object is allocated on the heap and lives until
garbage collected.
>What if method2 was called from method1, and x is passed in. Would the x
used in method2 be the same x from method1?

Yes, the object used would be the same.
>If I wanted it to be would x have to be declared outside both those
methods where my example global var i is?

No. When you pass the reference to another method, that reference becomes
a new local variable in that method, with it's own scope. You have two
reference variables with different scopes that reference the same object,
and as I said the object itself doesn't have any scope at all.

--
Göran Andersson
_____
http://www.guffa.com

May 11 '07 #15

P: n/a
On Thu, 10 May 2007 13:24:54 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
[...]
For parameters passed by reference, it's a very interesting question
which I hadn't thought of before.

I had to consult the docs, and what happens is that the parameter is
effectively passed by value instead of by reference, but the value at
the end of the asynchronous call is available when you call EndInvoke
instead.
Can you provide a link to the docs that describe that behavior? I'd love
to see what the specific syntax is for getting at the ref parameter.

Thanks!
Pete
May 20 '07 #16

P: n/a
Peter Duniho <Np*********@nnowslpianmk.comwrote:
[...]
For parameters passed by reference, it's a very interesting question
which I hadn't thought of before.

I had to consult the docs, and what happens is that the parameter is
effectively passed by value instead of by reference, but the value at
the end of the asynchronous call is available when you call EndInvoke
instead.

Can you provide a link to the docs that describe that behavior? I'd love
to see what the specific syntax is for getting at the ref parameter.
The easiest way to find the syntax is to compile a delegate type with a
ref parameter, and use ildasm or reflector to look at the signature of
EndInvoke. For instance:

delegate void Foo(ref int x, out int y, int z);

creates an EndInvoke method of:

void EndInvoke (ref x, out y, IAsyncResult result)

As for the documentation of this - it's briefly described in the ECMA-
335 spec, section 14.6.3.2, but trying it gives a more concrete feel :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 20 '07 #17

P: n/a
On Sat, 19 May 2007 23:47:22 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
[...]
As for the documentation of this - it's briefly described in the ECMA-
335 spec, section 14.6.3.2, but trying it gives a more concrete feel :)
Thanks. I think it's unfortunate that using "ildasm or reflector" is the
easiest way to answer my question. IMHO, the docs for EndInvoke ought to
include this information. :( The concept is documented on a more general
"calling synchronous methods asynchronously" page
(http://msdn2.microsoft.com/en-us/library/2e08f6yc.aspx), but it's a
pretty subtle reference.

Ah well...at least it's possible. Documentation can be improved. :)

Pete
May 20 '07 #18

P: n/a
Peter Duniho <Np*********@nnowslpianmk.comwrote:
[...]
As for the documentation of this - it's briefly described in the ECMA-
335 spec, section 14.6.3.2, but trying it gives a more concrete feel :)

Thanks. I think it's unfortunate that using "ildasm or reflector" is the
easiest way to answer my question. IMHO, the docs for EndInvoke ought to
include this information. :(
The trouble is that because EndInvoke is created separately for every
delegate, there *is* no Delegate.EndInvoke to have good documentation.
The concept is documented on a more general
"calling synchronous methods asynchronously" page
(http://msdn2.microsoft.com/en-us/library/2e08f6yc.aspx), but it's a
pretty subtle reference.

Ah well...at least it's possible. Documentation can be improved. :)
Indeed. I suspect it's a *very* rare case...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 20 '07 #19

P: n/a
On Sun, 20 May 2007 10:28:50 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:
The trouble is that because EndInvoke is created separately for every
delegate, there *is* no Delegate.EndInvoke to have good documentation.
Yet another "Control.Invoke vs Delegate.Invoke" issue?

There *is* a doc page for Control.EndInvoke(). I naively have assumed
that the same concepts apply to both, and that since you can call
EndInvoke on a delegate and get "ref" and "out" parameters, you can do the
same with Control instances.

But now that you point out the lack of a Delegate.EndInvoke() doc page, I
note that Control.EndInvoke() is a specific method attached to the Control
class, rather than being auto-generated according to the delegate being
used (just as Control.Invoke() or Control.BeginInvoke() is a specific
method, and requires passing of parameters as an array in a single
parameter, rather than using the signature provided for by the delegate
being invoked).

Nonetheless, just because EndInvoke() is different for each delegate,
according to its signature, I don't see why there should not be a doc page
for it. After all, I got to the page that describes the
Delegate.EndInvoke() syntax from the Control.EndInvoke() doc page.
Obviously there's some room for less-concrete contexts for documentation.
>Ah well...at least it's possible. Documentation can be improved. :)

Indeed. I suspect it's a *very* rare case...
True. And as I think I've mentioned previously, I think that's a good
thing. I can't imagine many, if any, scenarios in which passing "ref" or
"out" to an asynchronously-invoked delegate could be shown to be good
design. Still, one of my biggest complaints about programming has always
been, and continues to be, the poor documentation. I think MSDN has made
great strides beyond what I used to have to deal with, but there are still
places it could be *lots* better.

Pete
May 20 '07 #20

P: n/a
Peter Duniho <Np*********@nnowslpianmk.comwrote:
The trouble is that because EndInvoke is created separately for every
delegate, there *is* no Delegate.EndInvoke to have good documentation.

Yet another "Control.Invoke vs Delegate.Invoke" issue?
:)
There *is* a doc page for Control.EndInvoke(). I naively have assumed
that the same concepts apply to both, and that since you can call
EndInvoke on a delegate and get "ref" and "out" parameters, you can do the
same with Control instances.

But now that you point out the lack of a Delegate.EndInvoke() doc page, I
note that Control.EndInvoke() is a specific method attached to the Control
class, rather than being auto-generated according to the delegate being
used (just as Control.Invoke() or Control.BeginInvoke() is a specific
method, and requires passing of parameters as an array in a single
parameter, rather than using the signature provided for by the delegate
being invoked).
Exactly. It can't be auto-generated according to the delegate being
used, because the Control class doesn't know what kind of delegate you
might have defined.

Nonetheless, just because EndInvoke() is different for each delegate,
according to its signature, I don't see why there should not be a doc page
for it. After all, I got to the page that describes the
Delegate.EndInvoke() syntax from the Control.EndInvoke() doc page.
Obviously there's some room for less-concrete contexts for documentation.
There can certainly be documentation *about* it, just not the normal
sort of "Here's a method and its signature, and what it does"
autogenerated from XML comments.

There'd certainly be nothing to stop the Delegate type "about" page
having a link to a page about asynchronous execution (and I guess it
probably does).
Ah well...at least it's possible. Documentation can be improved. :)
Indeed. I suspect it's a *very* rare case...

True. And as I think I've mentioned previously, I think that's a good
thing. I can't imagine many, if any, scenarios in which passing "ref" or
"out" to an asynchronously-invoked delegate could be shown to be good
design.
Indeed. Heck, I try to avoid ref/out in synchronous calls, let alone
asynchronous :)
Still, one of my biggest complaints about programming has always
been, and continues to be, the poor documentation. I think MSDN has made
great strides beyond what I used to have to deal with, but there are still
places it could be *lots* better.
Indeed. And it's been flat out wrong and misleading in plenty of
places. (For a long time it claimed that decimal was a fixed point
type, which was my personal bugbear.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 20 '07 #21

This discussion thread is closed

Replies have been disabled for this discussion.