Caller Type ?

  • Thread starter Thread starter Genival
  • Start date Start date
G

Genival

Hello all...
First sorry my bad English.
Look next code

Dim oDS as Dataset ' <= Caller
oDs = MyFunc

'other caller type
Dim i as integer = MyFunc

public MyFunc(....) as object

Question : How do to detect caller type inside a method ?
Because i need return value casted.

if ??? is GetType(DataSet) then
return CType(ret as DataSet)
else if
bla bla bla...
End Func

Regards
Genival Carvalho
 
Genival said:
Hello all...
First sorry my bad English.
Look next code

Dim oDS as Dataset ' <= Caller
oDs = MyFunc

'other caller type
Dim i as integer = MyFunc

public MyFunc(....) as object

Question : How do to detect caller type inside a method ?
Because i need return value casted.

if ??? is GetType(DataSet) then
return CType(ret as DataSet)
else if
bla bla bla...
End Func


You should not care about the caller. Write two functions. One function
returns one type, the other function returns a different type.
 
Question : How do to detect caller type inside a method ?

The short answer is that you can't.

You could use overloaded functions and a ByRef parameter to return the
result instead.

Sub MyFunc(ByRef ds As Dataset)
Sub MyFunc(ByRef i As Integer)

....

Dim oDS As Dataset
MyFunc(oDS)

Or you could follow the pattern used by some framework classes, and
use separate methods for each possible return type

Function MyFuncDataset() As Dataset
Function MyFuncInt32() As Dataset



Mattias
 
But...
Inside ConvertTo i have this :
InstanceDescriptor
I can't use this feature inside my func ?

Regards
Genival Carvalho
 
Hi Genival,

|| Inside ConvertTo i have this :
|| InstanceDescriptor

There's no way for us to know what you are doing with so little information. It would be better if you gave us a fuller example.


Having said that, I'll try and explain a few things.

|| Dim oDS as Dataset ' <= Caller
|| oDs = MyFunc
||
|| 'other caller type
|| Dim i as integer = MyFunc
||
|| public MyFunc(....) as object
||
|| Question : How do to detect caller type inside a method ?
|| Because i need return value casted.

There is <no way> that a function can know <anything> about its caller unless it is <told>. So while MyFunc() above could be
called, as you show, with a DatSet or an Integer, etc, it <doesn't know>.

One way round this is to add an extra parameter to MyFunc():
Public Function MyFunc (..., oCaller As Object) As Object

You would use it like so:
oDs = MyFunc (..., oDs)
Dim i as integer = MyFunc (..., i)

Then, inside MyFunc(), you would be able to test the type of this last parameter.

Public Function MyFunc (..., oCaller As Object) As Object
If TypeOf oCaller Is DataSet Then
Return <some DataSet value>
If TypeOf oCaller Is Integer Then

Return <some Integer value>

That's how you <could> do it.

=================================
But in VB.NET that is very bad programming!!
There are much better ways to achieve the same effect.

=================================
One approach is to do what Armin and Mattias suggested:

Public Function MyFuncForDataSets (...) As DataSet
Return <some DataSet value>

Public Function MyFuncForIntegers (...) As Integer
Return <some Integer value>

You'd then call them like this:

oDS = MyFuncForDataSets (...)
i = MyFuncForIntegers (...)

=================================
Another is to use Mattias' first suggestion:

Public Sub MyFunc(ByRef ds As Dataset, ...)

ds = <some DataSet value>

Public Sub MyFunc(ByRef i As Integer, ...)

i = <some Integer value>

Notice that this time they are Subs, not Functions.
You'd call them like this:

MyFunc (oDS, ...) 'This would call the DataSet version
MyFunc (i, ...) 'This would call the Integer version.

This uses something called "overloading" which allows you to use the same function name for different values. The compiler sorts
out which of the several versions of the same function it should use, depending on the type of the value.

=================================
However, as you've come back with a new query, I'm wondering whether you didn't understand the previous answers to your question
or whether they simply don't work for you??

For that you must tell us more about what you are doing.

Regards,
Fergus
 
Why is passing a 'caller' object as a parameter to a procedure and testing
it's type within the procedure 'very bad programming' in VB.Net.?

It is exactly how event handlers are constructed with the sender As
System.Object parameter.

Fergus Cooney said:
Hi Genival,

|| Inside ConvertTo i have this :
|| InstanceDescriptor

There's no way for us to know what you are doing with so little
information. It would be better if you gave us a fuller example.
Having said that, I'll try and explain a few things.

|| Dim oDS as Dataset ' <= Caller
|| oDs = MyFunc
||
|| 'other caller type
|| Dim i as integer = MyFunc
||
|| public MyFunc(....) as object
||
|| Question : How do to detect caller type inside a method ?
|| Because i need return value casted.

There is <no way> that a function can know <anything> about its caller
unless it is said:
called, as you show, with a DatSet or an Integer, etc, it <doesn't know>.

One way round this is to add an extra parameter to MyFunc():
Public Function MyFunc (..., oCaller As Object) As Object

You would use it like so:
oDs = MyFunc (..., oDs)
Dim i as integer = MyFunc (..., i)

Then, inside MyFunc(), you would be able to test the type of this last parameter.

Public Function MyFunc (..., oCaller As Object) As Object
If TypeOf oCaller Is DataSet Then
Return <some DataSet value>
If TypeOf oCaller Is Integer Then

Return <some Integer value>

That's how you <could> do it.

=================================
But in VB.NET that is very bad programming!!
There are much better ways to achieve the same effect.

=================================
One approach is to do what Armin and Mattias suggested:

Public Function MyFuncForDataSets (...) As DataSet
Return <some DataSet value>

Public Function MyFuncForIntegers (...) As Integer
Return <some Integer value>

You'd then call them like this:

oDS = MyFuncForDataSets (...)
i = MyFuncForIntegers (...)

=================================
Another is to use Mattias' first suggestion:

Public Sub MyFunc(ByRef ds As Dataset, ...)

ds = <some DataSet value>

Public Sub MyFunc(ByRef i As Integer, ...)

i = <some Integer value>

Notice that this time they are Subs, not Functions.
You'd call them like this:

MyFunc (oDS, ...) 'This would call the DataSet version
MyFunc (i, ...) 'This would call the Integer version.

This uses something called "overloading" which allows you to use the
same function name for different values. The compiler sorts
out which of the several versions of the same function it should use,
depending on the type of the value.
=================================
However, as you've come back with a new query, I'm wondering whether
you didn't understand the previous answers to your question
 
Not quite correct, events do not have different return types, which is what
the original poster is asking for.
They want to have a different return type depending on what the result of
the function 'will' be assigned to.

Notice I said 'will'.... I'm sure if someone wanted to break out the
assembler, the function is being interpreted as an expression, then the
result of that expression is being assigned to the variable. There is a
distinct boundary there where the function will NOT know what object
variable its return value 'will' be assigned to.

The only way to do this, that I can tell, is to specific a parameter to the
function saying which return type to use. I just read somewhere that VB.NET
does NOT allow overloading functions based solely on return types, however
C# and C++ does.

Now, if the original poster wanted to format their function 'like' an event,
then it would be something along MyFunc(resultvar as Object) and the
resultvar object could be queried to determine the type to assign to it,
however, I am not quite sure of the exact formatting of that to allow you to
modify the variable itself. I think it is different in VB.NET now than it
was in VB6.
 
Hi Stephany,

Fergus wrote:
|| > Public Function MyFunc (..., oCaller As Object) As Object
|| >
|| > But in VB.NET that is very bad programming!!
|| > There are much better ways to achieve the same effect.

General life principle:
When there are better ways to achieve a given effect, choosing a non-better way is bad, maybe even 'very bad'.

In this case, the purpose of oCaller is solely to say what type of variable is on the receiving end of an assignment using
MyFunc(). If you read Genival's question and the answers again, and decide what solution <you> would implement, I'd be surprised if
you end up with a MyFunc like the one above.

Stephany wrote:
|| Why is passing a 'caller' object as a parameter to a procedure, and
|| testing it's type within the procedure, 'very bad programming' in VB.Net.?

My statement was referring to the code above it and was not a comment about passing Objects in general. However...

I don't think passing in Objects is good practice if it means that there must be code to work out whether it's a valid object
and what to do in each case, etc. It's fine if your method works polymorphically, although I think the object type should be as
restrictive as possible, ie using the highest possible base class or an interface.

|| It is exactly how event handlers are constructed with the
|| sender As System.Object parameter

I'd love to have event handlers that had specific types. [Not to mention a decent name. "sender" has never grabbed me as
particularly useful.] An event handler, eg KeyPress, must cater for any object that could possibly expect a key press. Plenty of
these objects have yet to be invented. Therefore the KeyPress Event Handler has to have an Object as its parameter.

If you know in advance what types a method of yours is going to have to cater for, you are in the position of using VB.NET to
its fullest and choosing one of the 'better ways'.

If overloads, virtual methods or specialised methods can be used instead of passing Objects around, then more of the the
type-checking can be left to the compiler.

Regards,
Fergus
 
But ... but ... but ...

The original poster is looking for:

public MyFunc(....) as object

Which means that he is NOT interested in the type of the return value at the
point at which it is returned.
 
I agree in principle with what you are saying. I was really commenting on
what appeared to be pretty broad-brush.

In my opinion it really comes down to a matter of trade-offs, which, of
course, is another general life principle.

If one has a single encapsulated function a'la:

Public MyFunc(oCaller As Object) As Object
Select Case oCaller.GetType.Name
Case "abc"
Return whatever
Case else
Return whateverelse
End Select
End Function

as opposed to a number of overloaded functions to handle all known object
types and one comes up with a new object type then I know which approach I
would rather maintain.

I believe it is more a case of 'what works for you' rather than aiming for
'acedemic correctness'.


Fergus Cooney said:
Hi Stephany,

Fergus wrote:
|| > Public Function MyFunc (..., oCaller As Object) As Object
|| >
|| > But in VB.NET that is very bad programming!!
|| > There are much better ways to achieve the same effect.

General life principle:
When there are better ways to achieve a given effect, choosing a
non-better way is bad, maybe even 'very bad'.
In this case, the purpose of oCaller is solely to say what type of
variable is on the receiving end of an assignment using
MyFunc(). If you read Genival's question and the answers again, and decide
what solution said:
you end up with a MyFunc like the one above.

Stephany wrote:
|| Why is passing a 'caller' object as a parameter to a procedure, and
|| testing it's type within the procedure, 'very bad programming' in VB.Net.?

My statement was referring to the code above it and was not a comment
about passing Objects in general. However...
I don't think passing in Objects is good practice if it means that
there must be code to work out whether it's a valid object
and what to do in each case, etc. It's fine if your method works
polymorphically, although I think the object type should be as
restrictive as possible, ie using the highest possible base class or an interface.

|| It is exactly how event handlers are constructed with the
|| sender As System.Object parameter

I'd love to have event handlers that had specific types. [Not to
mention a decent name. "sender" has never grabbed me as
particularly useful.] An event handler, eg KeyPress, must cater for any
object that could possibly expect a key press. Plenty of
these objects have yet to be invented. Therefore the KeyPress Event
Handler has to have an Object as its parameter.
If you know in advance what types a method of yours is going to have
to cater for, you are in the position of using VB.NET to
its fullest and choosing one of the 'better ways'.

If overloads, virtual methods or specialised methods can be used
instead of passing Objects around, then more of the the
 
Hi Stephany,

Certainly if MyFunc is short then there is a benefit in having the one function which caters for all. A sprinkling of tiny
overloads may only produce volume without substance in such a case.

If MyFunc is stable then the advantage is maintained. Often the function in question gets bigger and bigger as more
functionality, more error checking, etc is added. Then a one-function-for-all would benefit from being chopped up - maybe even
reconfigured as overloads or whatever. Starting out with overloads as little thin things, the expansion would flesh them out without
them becoming unwieldy. Swings and roundabouts.

You sound like more of a let's-do-just-enough-for-the-job-right-now type. I am more of a cater-for-the future "purist". It's a
matter of personal style. You are probably quicker than me at producing code. I may be quicker at adapting/enhancing my code further
down the road. Who knows.

Regards,
Fergus
 
Many thankZ guys...

I will use Another Mattias' first suggestion: (temporary)
Public Sub MyFunc(ByRef ds As Dataset, ...)
ds = <some DataSet value>

Public Sub MyFunc(ByRef i As Integer, ...)
i = <some Integer value>

But... i think that it isn't a elegant solution, if the way to solve my
problem is use C# or C++ i will use it, have anyone a example ?
Regards
Genival Carvalho
 
Genival said:
Many thankZ guys...

I will use Another Mattias' first suggestion: (temporary)
Public Sub MyFunc(ByRef ds As Dataset, ...)
ds = <some DataSet value>

Public Sub MyFunc(ByRef i As Integer, ...)
i = <some Integer value>

But... i think that it isn't a elegant solution, if the way to solve
my
problem is use C# or C++ i will use it, have anyone a example ?
Regards
Genival Carvalho

If you would tell us what exactly you're trying to do, we could give the
best answer.
 
OK:
I have 2 methods :

1) Public Function Execute() As DataSet

....

oAdapter.Fill(oDataSet)

Return oDataSet

end functio

2)

Public Function ExecuteNonQuery() As Integer

....

Return oCmd.ExecuteNonQuery()

end function



When client call this functios this need know how datatype the client
receive, befor make a call:

Dim X as integer = ExecituNoQuery

or

Dim oDS as dataset = Execute

I think that it is not a best way do make a call...

Think :

DIm i as integer = Execute()

or

Dim oDS as dataset = Execute

like me more smart, but in this way i need inside method Execute how
datatype Caller is : ( integer or dataset or etc...)

Regards

Genival Carvalho
 
Genival said:
OK:
I have 2 methods :

1) Public Function Execute() As DataSet

...

oAdapter.Fill(oDataSet)

Return oDataSet

end functio

2)

Public Function ExecuteNonQuery() As Integer

...

Return oCmd.ExecuteNonQuery()

end function



When client call this functios this need know how datatype the client
receive, befor make a call:

Dim X as integer = ExecituNoQuery

or

Dim oDS as dataset = Execute

I think that it is not a best way do make a call...

Think :

DIm i as integer = Execute()

or

Dim oDS as dataset = Execute

like me more smart, but in this way i need inside method Execute how
datatype Caller is : ( integer or dataset or etc...)


You have two different tasks. One creates a Dataset, the other executes
ExecuteNonQuery. Now you can write two procedures. Each procedure has it's
own task. An alternative is to put two tasks into the same procedure, but
then you need to tell the procedure which task it has to do. As we now can
write overloaded procedures, we can choose the same procedure name for
different tasks, but the compiler has to know which of the two procedures
has to be called. The compiler tries to find the right procedure depending
on the types of the arguments you pass to the procedure.

So, the type of the variable used to assign the function's result can not be
used to find the procedure to be called because the assignment is done
*after* the function has been called. Apart from this, the compiler wouldn't
know which function to call with
dim o as object = Execute()


I hope I didn't repeat too much of what has already been said. :)
 
Back
Top