Method Signature For A Method That Can Return Objects and PrimitiveData Types...

S

Sunburned Surveyor

I'm a Java developer in the process of writing a class library in C#,
so please bear with me.

I'm trying to write a method that can return a generic Object OR a
Decimal value. In Java I would just have the method return an Object,
since all Java primitive data types have Object wrappers like Integer
and Double.

If I have a method signature that returns Object in C#, can I return a
Decimal value within the method body? I was looking online at it
appears that Decimal is a Struct, not a Class, so I'm not sure if this
is legal.

Thanks for help with the solution.

The Sunburned Surveyor
 
P

Peter Duniho

[...]
If I have a method signature that returns Object in C#, can I return a
Decimal value within the method body? I was looking online at it
appears that Decimal is a Struct, not a Class, so I'm not sure if this
is legal.

It is.

You may want to read up on "boxing", as returning a value type as an
"object" will force the value type to be wrapped in a reference type
instance (boxed). Casting back to decimal will unbox it, allowing it to
be assigned to a variable of the correct value type (decimal in this case,
of course).

Of course, you could have just tried it to see if it works. :)

Pete
 
S

Scott Roberts

Peter Duniho said:
[...]
If I have a method signature that returns Object in C#, can I return a
Decimal value within the method body? I was looking online at it
appears that Decimal is a Struct, not a Class, so I'm not sure if this
is legal.

It is.

You may want to read up on "boxing", as returning a value type as an
"object" will force the value type to be wrapped in a reference type
instance (boxed). Casting back to decimal will unbox it, allowing it to
be assigned to a variable of the correct value type (decimal in this case,
of course).

Of course, you could have just tried it to see if it works. :)

Pete


An addendum to Pete's excellent advice: "boxing" is very slow.

If you intend to call this method very often, you should seriously consider
simply creating a new method.

Another option would be to use overloaded methods with an "out" parameter
instead of a function result. This assumes, of course, that you know the
type of the "result" before you call the method.

If I had to guess, I'd say you're writing some sort of "WinAPI"-ish function
which returns an object if it succeeds and an error code if it fails. In
that case, you might consider always returning a decimal (0 = success) and
using an "out" parameter for your success "result".
 
S

Sunburned Surveyor

On Thu, 20 Dec 2007 09:57:20 -0800, Sunburned Surveyor
[...]
If I have a method signature that returns Object in C#, can I return a
Decimal value within the method body? I was looking online at it
appears that Decimal is a Struct, not a Class, so I'm not sure if this
is legal.
You may want to read up on "boxing", as returning a value type as an
"object" will force the value type to be wrapped in a reference type
instance (boxed). Casting back to decimal will unbox it, allowing it to
be assigned to a variable of the correct value type (decimal in this case,
of course).
Of course, you could have just tried it to see if it works. :)

An addendum to Pete's excellent advice: "boxing" is very slow.

If you intend to call this method very often, you should seriously consider
simply creating a new method.

Another option would be to use overloaded methods with an "out" parameter
instead of a function result. This assumes, of course, that you know the
type of the "result" before you call the method.

If I had to guess, I'd say you're writing some sort of "WinAPI"-ish function
which returns an object if it succeeds and an error code if it fails. In
that case, you might consider always returning a decimal (0 = success) and
using an "out" parameter for your success "result".- Hide quoted text -

- Show quoted text -

Thanks for the responses Scott an Peter. I'm actually defining the
method as part of an interface. In most cases the implementations of
this interface will simply return a Decimal value from this particular
method. However, the occassional implementation of this interface may
want to return a custom object from this method.

It sounds like I may need to just provide a method for the custom
object access.

Thanks again for the help.

The Sunburned Surveyor
 
J

Jon Skeet [C# MVP]

An addendum to Pete's excellent advice: "boxing" is very slow.

"Very slow"? It's actually really, really fast - unless you're using it
millions of times, of course. It's not free, and should be carefully
considered, but I don't think I'd really call it "very slow".
If you intend to call this method very often, you should seriously consider
simply creating a new method.

Again, it depends on what you call "very often". In a microbenchmark
(with all the caveats they always involve) I can box an integer about
100 million times in a single second on my laptop.

So, if you're "only" going to call the method a few thousand times a
second, I don't think the performance penalty is likely to be
significant.

If I had to guess, I'd say you're writing some sort of "WinAPI"-ish function
which returns an object if it succeeds and an error code if it fails. In
that case, you might consider always returning a decimal (0 = success) and
using an "out" parameter for your success "result".

Or preferably use an exception for failure cases.
 
S

Scott Roberts

Jon Skeet said:
"Very slow"? It's actually really, really fast - unless you're using it
millions of times, of course. It's not free, and should be carefully
considered, but I don't think I'd really call it "very slow".


Again, it depends on what you call "very often". In a microbenchmark
(with all the caveats they always involve) I can box an integer about
100 million times in a single second on my laptop.

So, if you're "only" going to call the method a few thousand times a
second, I don't think the performance penalty is likely to be
significant.

I'll defer to your expertise, but we used boxing extensively in our OPF and
saw marked improvement when we switched to native types.
Or preferably use an exception for failure cases.

I can say for certain that exceptions are "very slow". ;)
 
S

Scott Roberts

Arne Vajhøj said:
Exceptions are for exceptional situations - they can not
happen frequently.

Arne

Exactly my point. If "failure" happens frequently, then exceptions are not
the answer.
 
J

Jon Skeet [C# MVP]

I can say for certain that exceptions are "very slow". ;)

When used properly, they are not a performance issue. You'll see a
performance hit if you throw hundreds of thousands of exceptions, but
they're not nearly as bad as people make them out to be.

The way people talk about them, you'd think they took a second or so to
throw.
 
J

Jon Skeet [C# MVP]

Scott Roberts said:
I'll defer to your expertise, but we used boxing extensively in our OPF and
saw marked improvement when we switched to native types.

Then I suspect you were in the case of using them hundreds of thousands
of times a second.
 
S

Scott Roberts

Jon Skeet said:
When used properly, they are not a performance issue. You'll see a
performance hit if you throw hundreds of thousands of exceptions, but
they're not nearly as bad as people make them out to be.

The way people talk about them, you'd think they took a second or so to
throw.

If you throw hundreds of thousands of them your application will come
crashing to its knees. We have a process that rates telephone calls. We rate
batches containing several million at a time. There are many, many, many
things that can be "wrong" with a record that prevents it from being rated
properly. My first iteration used exceptions when something went wrong. It
was unusable. I switched to "error codes" and now it takes a few minutes.
"Performance hit" is putting it mildly.

I'm not sure how my simple comment to a new .net developer (coming from the
world of Java) that boxing is less performant than native types turned into
a discussion about the "proper" use of exceptions. I even qualified my
observation by saying that it would only be an issue if the method were
called very frequently. I tried to draw a conclusion (use of return codes)
from the OP's question, assumed there was a reason for it (using return
codes), and attempted to offer a solution. Sorry if that pushed one of your
buttons.
 
J

Jon Skeet [C# MVP]

Scott Roberts said:
If you throw hundreds of thousands of them your application will come
crashing to its knees.

Well, it will take tens of seconds to throw them.
We have a process that rates telephone calls. We rate
batches containing several million at a time. There are many, many, many
things that can be "wrong" with a record that prevents it from being rated
properly. My first iteration used exceptions when something went wrong. It
was unusable. I switched to "error codes" and now it takes a few minutes.
"Performance hit" is putting it mildly.

In a situation where it's reasonably expected for records to be
"wrong", yes. That's the ideal time *not* to use exceptions. That's why
I said they're not a performance issue when used properly.
I'm not sure how my simple comment to a new .net developer (coming from the
world of Java) that boxing is less performant than native types turned into
a discussion about the "proper" use of exceptions.

You didn't say that boxing is "less performant than native types". You
said it was "very slow". There's a massive difference between those
statements. The first is true. The second is an overstatement, in my
view.
I even qualified my observation by saying that it would only be an
issue if the method were called very frequently.

Well, again that's not *quite* what you said - but it certainly gave
the wrong impression, IMO.
I tried to draw a conclusion (use of return codes)
from the OP's question, assumed there was a reason for it (using return
codes), and attempted to offer a solution. Sorry if that pushed one of your
buttons.

People often bend perfectly reasonable designs out of shape to avoid
boxing and exceptions precisely because of claims that they are "very
slow" when actually they're only going to call the relevant routine a
few thousand times an hour.

In one discussion, people seriously claimed that a few hundred
exceptions being thrown in an hour would be a significant performance
hit for a web application. See how these things get out of control?
 
S

Scott Roberts

In one discussion, people seriously claimed that a few hundred
exceptions being thrown in an hour would be a significant performance
hit for a web application. See how these things get out of control?

I'm not going to argue semantics with you. Suffice it to say, this was not
one of those discussions.
 
J

Jon Skeet [C# MVP]

Scott Roberts said:
I'm not going to argue semantics with you. Suffice it to say, this was not
one of those discussions.

I never said it was - merely that people take away impressions from
phrases like "very slow" which *lead* to discussions like that.

Do you really not appreciate that there's a significant difference
between "less performant than native types" and "very slow"? It's not
just splitting hairs, it's a definite difference which could easily
influence people in their coding when it shouldn't.
 
S

Scott Roberts

Jon Skeet said:
I never said it was - merely that people take away impressions from
phrases like "very slow" which *lead* to discussions like that.

Do you really not appreciate that there's a significant difference
between "less performant than native types" and "very slow"? It's not
just splitting hairs, it's a definite difference which could easily
influence people in their coding when it shouldn't.

It could also influence people in their coding when it should. The fact of
the matter is, you didn't bother to find out if boxing and/or exceptions
were "proper" for the OPs request, you just said he should do it. I inferred
that if he were using return codes in the first place that there was a
reason (frequent "errors"). I think that your recommending these techniques
without bothering to mention the performance drawbacks is, quite frankly,
irresponsible on your part. These kinds of blanket recommendations *lead* to
programmers all over the world thinking .Net is "very slow".

And since you ask, I do think that 20 times longer qualifies as "very slow".
That's just my opinion and you are unlikely to change it.

"Boxing and unboxing are computationally expensive processes. When a value
type is boxed, an entirely new object must be created. This can take up to
20 times longer than an assignment. When unboxing, the casting process can
take four times as long as an assignment."

http://msdn2.microsoft.com/en-us/library/ms173196(VS.80).aspx
 
J

Jon Skeet [C# MVP]

Scott Roberts said:
It could also influence people in their coding when it should. The fact of
the matter is, you didn't bother to find out if boxing and/or exceptions
were "proper" for the OPs request, you just said he should do it. I inferred
that if he were using return codes in the first place that there was a
reason (frequent "errors"). I think that your recommending these techniques
without bothering to mention the performance drawbacks is, quite frankly,
irresponsible on your part. These kinds of blanket recommendations *lead* to
programmers all over the world thinking .Net is "very slow".

I don't think very many programs have actually been slow due to boxing
being a bottleneck, to be honest.
And since you ask, I do think that 20 times longer qualifies as "very slow".
That's just my opinion and you are unlikely to change it.

I suspect not. Then again, you're unlikely to change my opinion,
either. Boxing is very, very rarely a bottleneck in my experience.
"Boxing and unboxing are computationally expensive processes. When a value
type is boxed, an entirely new object must be created. This can take up to
20 times longer than an assignment. When unboxing, the casting process can
take four times as long as an assignment."

Wow, 20 times longer than an assignment. Assignments are *blazingly*
quick - it doesn't make boxing "very slow", just *relatively* slow.
Yes, it's slower than a straight assignment. Making a method call which
isn't inlined is much slower than making a call which *is* inlined -
but that doesn't make non-inlined method calls "very slow" either.

Yes, it's worth being aware of the penalty of boxing - but I've seen
far more code which is badly written due to micro-optimisation than I
have code which performs unacceptably due to boxing.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top