CSharp/C# >> Extension methods for value types

by Jesper Lund Stocholm » Thu, 21 Aug 2008 02:43:21 GMT

I am currently working on converting an old .Net 1.1-application to .Net
3.5. Due to the lack of nullable datatypes in those days, a "decimal
wrapper" was created that had various methods to parse objects (of
varying types) as well as methods to determine if the parsed decimal was
"valid", i.e. not null.

With nullable types we have some of it covered when creating the
functionality in .Net 3.5, but I am unsure how to create the
"sophisticated parsing". I thought about implementing an extension method
to facilitate code like

decimal? d = default (decimal);
d.ParseMe(1.2d);
if (d.HasValue)
{
// do stuff
}

A simple version of .ParseMe() would be

public static decimal? ParseMe(object o)
{
decimal? d = default(decimal);
try
{
d = Decimal.Parse(o.ToString());
}
catch {}
return d;
}

So my question is: Can I make an extension method on a value type - and
how would I do this in my case?

Thanks, in advance

:o)

--
Jesper Lund Stocholm
http://idippedut.dk

CSharp/C# >> Extension methods for value types

by Peter Duniho » Thu, 21 Aug 2008 03:07:33 GMT


On Wed, 20 Aug 2008 11:43:21 -0700, Jesper Lund Stocholm



You can extend classes and interfaces, not value types.

But I'm not clear on why you want to do this. Why not just call
Decimal.Parse() or Decimal.TryParse() directly in your own code?

Pete

CSharp/C# >> Extension methods for value types

by Peter Duniho » Thu, 21 Aug 2008 03:13:50 GMT

On Wed, 20 Aug 2008 12:07:33 -0700, Peter Duniho




Sorry, spoke too soon. You can extend value types too.

But I still don't know why you want to. :)

CSharp/C# >> Extension methods for value types

by Jon Skeet [C# MVP] » Thu, 21 Aug 2008 03:36:25 GMT


<snip>


I've found the following methods very handy for unit testing, when I
want a quick way of getting dates and times. They're not what you'd
often use in production (where you're typically specifying the month
via a variable rather than effectively hard-coding it) but "just for
unit tests" is still useful :)

public static DateTime January(this int day, int year)
{
return new DateTime(year, 1, day);
}

public static DateTime February(this int day, int year)
{
return new DateTime(year, 2, day);
}

etc

Then:

public static TimeSpan Milliseconds(this int milliseconds)
{
return TimeSpan.FromMilliseconds(milliseconds);
}

public static TimeSpan Seconds(this int seconds)
{
return TimeSpan.FromSeconds(seconds);
}

public static TimeSpan Minutes(this int minutes)
{
return TimeSpan.FromMinutes(minutes);
}

etc.


So then we have in the unit tests:

DateTime birthday = 19.June(1976) + 8.Hours();

Very readable, IMO.

--
Jon Skeet - < XXXX@XXXXX.COM >
Web site: http://www.pobox.com/ ~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com

CSharp/C# >> Extension methods for value types

by Jesper Lund Stocholm » Thu, 21 Aug 2008 03:37:45 GMT


Ok - thanks for clearing this out. Earlier today I stumpled over this
article [0] - so he is wrong? As I read the code (that I cannot get to
work or even compile, btw) it seems he is doing exactly that.

Well, I am a little unsure of this too. The issue is that the existing
fucntionality has the following ctor:

class MyDecimalWrapper
{
private decimal m_decimal = 0;

public MyDecimalWrapper(object o)
{
// ...
}

public override string ToString()
{
if (IsValid)
{
return "";
}
else
{
return m_decimal.ToString();
}
}
}

Where o can be literally everything. The method parses this object and
sets a property ( .IsValid ) if conversion goes through. This enables
me to assigning e.g. the ToString()-value to controls etc without worrying
about the internal value being valid (or null) and thus throwing a
NullReferenceException.

With the nullable decimal I have the .NasValue-property that I can use
to replace the above - but the method Decimal.TryParse() does not
accept a nullable decimal ... just the "regular" one.

I am very much open for suggestions to how to accomplish this.

:o)

Thank you for your time so far.

[0] http://www.codemeit.com/code-collection/c-extension-method-getvalueornull.html

--
Jesper Lund Stocholm
http://idippedut.dk

CSharp/C# >> Extension methods for value types

by Arne Vajh » Thu, 21 Aug 2008 07:25:40 GMT


For inspiration:

using System;

namespace E
{
public static class MyExtensions
{
public static decimal? SpecialParse(this decimal o, string s)
{
decimal res;
if(decimal.TryParse(s, out res))
{
return res;
}
else
{
return null;
}
}
public static decimal? ToDecimal(this string s)
{
decimal res;
if(decimal.TryParse(s, out res))
{
return res;
}
else
{
return null;
}
}
}
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine(default(decimal).SpecialParse("123,45"));
Console.WriteLine(default(decimal).SpecialParse("ABC") ==
null);
Console.WriteLine("123,45".ToDecimal());
Console.WriteLine("ABC".ToDecimal() == null);
Console.ReadKey();
}
}
}

Arne

CSharp/C# >> Extension methods for value types

by Peter Duniho » Thu, 21 Aug 2008 08:25:42 GMT

On Wed, 20 Aug 2008 12:36:25 -0700, Jon Skeet [C# MVP] < XXXX@XXXXX.COM >




Sorry...my most recent statement is easily misunderstood out of context.

It's not that I don't see a use for extension methods on value types
generally. It's just that the OP's example doesn't seem to call for an
extension method. Maybe I'm missing something here, but it seems like he
ought to just call Parse() directly.

If he were actually returning null from the extension method on failure,
it might make more sense to me. But he's not, so it doesn't. :(

Pete

CSharp/C# >> Extension methods for value types

by Peter Duniho » Thu, 21 Aug 2008 08:29:42 GMT

On Wed, 20 Aug 2008 12:37:45 -0700, Jesper Lund Stocholm



As I mentioned in my immediate follow-up, my statement about not being
able to extend value types was incorrect.

As for further suggestions, I'm still having trouble understanding your
own examples, but it seems to me that the examples that Arne posted might
be useful. They do make more sense to me, anyway :), in that they return
null on failure. Especially the ToDecimal() method (I'm not particularly
fond of the use of a dummy default value for the SpecialParse() method).

Pete

CSharp/C# >> Extension methods for value types

by Jesper Lund Stocholm » Sun, 07 Sep 2008 05:31:48 GMT

Arne Vajh鴍 < XXXX@XXXXX.COM > wrote in





[snip code]

Thanks, Arne - that was exactly what I was looking for.

:o)

--
Jesper Lund Stocholm
http://idippedut.dk

Similar Threads

1. Extension method for static method? - CSharp/C#

2. How do I access another type's method from one type's method

ding feng wrote:

> I got this program:
> 
> class building{
> ...
> };
> 
> class school:public building{
> ...
> 
> int getstudentnumber(int m);
> };
> 
> class hospital:public building{
> ...
> 
> int reportpatientnumber();
> };
> 
> int hospital:reportpatientnumber()
> {
> //here I need to call school method getstudentnumber(int m);

A hospital is not a school, so you can't call school's member functions
for a hospital. Or did I misunderstand something?

> }
> 
> In hosptial:reportpatientnumber() method, I can't pass anything as a
> parameter, for example, can't pass a school type pointer. The
> parameter lists MUST be empty.

What does the int parameter do?

> Is there an alternative way to do that?

It's hard to tell from the information you provided.

3. Send refrence types by value to a method - CSharp/C#

4. Boxing and Unboxing of Value-Types when passed to a method call

Hi All,
First of all I think this is gonna be one of those threads :-) since I have
bunch of questions which make this very controversial:-0)
Ok,Let's see:

I was reading an article that When you pass a Value-Type to method call
,Boxing and Unboxing would happen,Consider the following snippet:
int a=1355;
myMethod(a);
.....
void myMethod(int b);

Can somebody describes what exactly happens in the stack and (probably in
the heap) when this code is executed?

Thanks for your time in advance,I will ask my other questions as we go
further with this thread.

Cheers,
Raza Alirezaei




5. Boxing and Unboxing of Value-Types when passed to a method cal - CSharp/C#

6. method ref to arbitrary value type instance

7. out method and method with return value - CSharp/C#

8. Checking if enum type value contains certain value

Hello,

Is there some short-gand way to check if the enum type value contains
certain value?

Ie, the talk here is about Regex object:

Regex re = new Regex(@"pattern", RegexOptions.IgnoreCase |
RegexOptions.Multiline);
if ((re.Options & RegexOptions.IgnoreCase) == RegexOptions.IgnoreCase) ...
do stuff ...

This "if" expression is rather lengthy, perhaps there is some shorter way to
check wether the value contains one of the ORed enum values?

Thanks,

Pavils