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

Code calls method with wrong signature (object vs object[])

P: n/a
Hello all,

I recently ran into a strange behavior which I don't understand. I
have two 'Add' method which a slightly different signature which they
look like

public void Add( string varName, ScriptVarType type, object value )
public void Add( string varName, ScriptVarType type, object[] values
)

Then in another part of the source base I have the following
declaration

private void Extract( ... )
{
byte[] byteElements;

...

// Where all arguments are assigned before the call is made
ScriptVars.Add( groupsRegEx[1].Value, type, byteElements );
}

The strange item which I don't understand is that instead of call the
method that accepts an array of objects the code is calling the method
where the signature only accepts a single object. Can someone explain
why this is? My guess is since object is the base class of most items
it is also the base class for arrays. Any explanation will be
appreciated. For the time being I will just end up change the method
names to force call to the correct method istead of relying on the
compiler looking at the signature. Thanks

Mark

Aug 15 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Mark,

The problem here is that arrays are not inherently polymorphic. So, as
a result, the compiler tries to match up the call with the appropriate
function, it sees that byte[] does not cast down to object[], but it does
cast down to object, and that's why the call is made.

You might want to try defining the parameter with the object array as
System.Array, and see if that works.

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

<Lo*****@hotmail.comwrote in message
news:11*********************@b28g2000cwb.googlegro ups.com...
Hello all,

I recently ran into a strange behavior which I don't understand. I
have two 'Add' method which a slightly different signature which they
look like

public void Add( string varName, ScriptVarType type, object value )
public void Add( string varName, ScriptVarType type, object[] values
)

Then in another part of the source base I have the following
declaration

private void Extract( ... )
{
byte[] byteElements;

...

// Where all arguments are assigned before the call is made
ScriptVars.Add( groupsRegEx[1].Value, type, byteElements );
}

The strange item which I don't understand is that instead of call the
method that accepts an array of objects the code is calling the method
where the signature only accepts a single object. Can someone explain
why this is? My guess is since object is the base class of most items
it is also the base class for arrays. Any explanation will be
appreciated. For the time being I will just end up change the method
names to force call to the correct method istead of relying on the
compiler looking at the signature. Thanks

Mark

Aug 15 '06 #2

P: n/a
Two simply workarounds leap to mind:
// 1: since Array is the base of all array implementations
public void Add( string varName, ScriptVarType type, Array values) {}

// 2: (2.0 only) generics;
// note you generally won't have to specify T
// when calling - i.e. declare an int[] vals and call Add(blah, vals);
public void Add<T>( string varName, ScriptVarType type, T[] values) {}

Marc
Aug 16 '06 #3

P: n/a
Lo*****@hotmail.com wrote:
The strange item which I don't understand is that instead of call the
method that accepts an array of objects the code is calling the method
where the signature only accepts a single object. Can someone explain
why this is? My guess is since object is the base class of most items
it is also the base class for arrays. Any explanation will be
appreciated. For the time being I will just end up change the method
names to force call to the correct method istead of relying on the
compiler looking at the signature.
Changing the method names won't help you, as a byte[] isn't an
object[]. The problem is that while *arrays of reference types* are
covariant, arrays of value types aren't. For instance:

string[] stringArray = new string[10];
object[] objectArray = stringArray; // Fine

but

byte[] byteArray = new byte[10];
int[] intArray = byteArray; // No conversion available
object[] objectArray = byteArray; // No conversion available

The other posts give suggested solutions.

Jon

Aug 16 '06 #4

P: n/a
Nicholas,

Thanks for the information as I didn't realize this until now.
Instead of passing in an array of byte, short or int I boxed them into
an array of objects them unboxed them within the called method. I don't
like this implementation as it is not all that elegant, but it will do
for now until I find a better approach.

Mark

Nicholas Paldino [.NET/C# MVP] wrote:
Mark,

The problem here is that arrays are not inherently polymorphic. So, as
a result, the compiler tries to match up the call with the appropriate
function, it sees that byte[] does not cast down to object[], but it does
cast down to object, and that's why the call is made.

You might want to try defining the parameter with the object array as
System.Array, and see if that works.

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

<Lo*****@hotmail.comwrote in message
news:11*********************@b28g2000cwb.googlegro ups.com...
Hello all,

I recently ran into a strange behavior which I don't understand. I
have two 'Add' method which a slightly different signature which they
look like

public void Add( string varName, ScriptVarType type, object value )
public void Add( string varName, ScriptVarType type, object[] values
)

Then in another part of the source base I have the following
declaration

private void Extract( ... )
{
byte[] byteElements;

...

// Where all arguments are assigned before the call is made
ScriptVars.Add( groupsRegEx[1].Value, type, byteElements );
}

The strange item which I don't understand is that instead of call the
method that accepts an array of objects the code is calling the method
where the signature only accepts a single object. Can someone explain
why this is? My guess is since object is the base class of most items
it is also the base class for arrays. Any explanation will be
appreciated. For the time being I will just end up change the method
names to force call to the correct method istead of relying on the
compiler looking at the signature. Thanks

Mark
Aug 16 '06 #5

P: n/a

Marc Gravell wrote:
Two simply workarounds leap to mind:
// 1: since Array is the base of all array implementations
public void Add( string varName, ScriptVarType type, Array values) {}

// 2: (2.0 only) generics;
// note you generally won't have to specify T
// when calling - i.e. declare an int[] vals and call Add(blah, vals);
public void Add<T>( string varName, ScriptVarType type, T[] values) {}

Marc

Marc,

I think the first solution you have provided provides me with a nice
approach and it does appear to work well. I would use the second
approach, but as in my first implementation of using generics for this
project I had to scrap it as the variable is not known at compile time
and only as a script file is parsed, thus I always get "Cannot convert
type 'T[]' to 'byte[]' or other data types.

Is there a nice way of dealing with this?

So if I have my method signature that looks like

public void Add<T>( string varName, ScriptVarType type, T[] values )

then depending upon the type of variable that is determined at run-time
I need to cast it to a byte, short, int, float or string (etc..). I
could provide a signature for each variable type, but I was hoping to
have one method that accepts the arguments and cast them to the
appropriate type. I am not quite sure what the best approach is. I
was also having issues using bitwise operation (masking) of generics as
I would always get compiler errors. I really was hoping to use
generics, but I ran into problems using them when I had value and ref
types mixed.

Mark

Aug 16 '06 #6

P: n/a
then depending upon the type of variable that is determined at run-time
I need to cast it to a byte, short, int, float or string (etc..).
Generics is not the solution to every problem, however, if you can elaborate
on what you are trying to do (perhaps a little pseudocode as to why you need
to know the specific types), then I might be able to help. The framework
provides a number of handy interfaces (which framework objects supprt) and
helper classes to assist with generics, such as IEquatable<T>,
IComparable<T>, EqualityComparer<T>.Default, etc.

Reflection is an option, but could be just as messy, and I don't like using
it if there is a perfectly good compile-time alternative available to me...
I was also having issues using bitwise operation (masking) of
generics as I would always get compiler errors.
What with things like ints, enums, etc? Yup, that's a right royal pain.
Can't be done neatly via generics AFAIK.
I ran into problems using them when I had value and ref
types mixed.
Anything specific? Note things like default(T), new(), and the : class / :
struct constraints may be of use. But again, generics is not a "fixes
everything ever" kind of thing. It helps though.

Marc
Aug 17 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.