Extend Types like instances?

J

Jon Slaughter

Can one extend the type itself and not just an instance of the type?

So I have something, say, like

public static DateTime RawRead(this DateTime i, Stream s)
{
BinaryReader b = new BinaryReader(s);
i = DateTime.FromBinary(b.ReadInt64());
return i;
}


But how I have to use it is

DateTime d = new DateTime();
d = d.RawRead(s);

I'd like to be able to do

DateTime d = DateTime.RawRead(s);

or even

DateTime d = new DateTime();
d.RawRead(s);


In a sense I need something like

public static DateTime RawRead(this ref DateTime i, Stream s)
{
BinaryReader b = new BinaryReader(s);
i = DateTime.FromBinary(b.ReadInt64());
}

But of course that doesn't work. (Or even a way to extend the type itself)

Ultimately its not that big a deal but its a little messy to have to use the
instance itself to call the method. (and for the fact that it creates two
objects since I first have to instantiate it then return a new one)

Thanks,
Jon
 
J

Jon Slaughter

Also, is it possible to override an extension? (I doubt it but I'd like to
be able to override any extensions later on that I've created without having
the source)
 
B

Ben Voigt [C++ MVP]

Jon said:
Also, is it possible to override an extension? (I doubt it but I'd
like to be able to override any extensions later on that I've created
without having the source)

Kinda. There's a particular order in which namespaces are searched to find
extension methods.
 
J

Jon Skeet [C# MVP]

Jon Slaughter said:
I guess my idea is bad though cause one cannot derive from a static class ;/
I was hoping there would be some way to modify some extension I previous did
if I lost the source code, for example. Say I extended DateTime but later
found a better way but lost the source code. It seems theres no way to
modify that extension? (assuming that I have to use the same name which I
would in my application)

Well, the way to do it is have a "using" directive for the namespace
containing the new set of extensions, and get rid of the one for the
old extensions.
 
J

Jon Slaughter

Ben Voigt said:
Kinda. There's a particular order in which namespaces are searched to
find extension methods.


I guess my idea is bad though cause one cannot derive from a static class ;/
I was hoping there would be some way to modify some extension I previous did
if I lost the source code, for example. Say I extended DateTime but later
found a better way but lost the source code. It seems theres no way to
modify that extension? (assuming that I have to use the same name which I
would in my application)
 
J

Jon Slaughter

Jon Skeet said:
Well, the way to do it is have a "using" directive for the namespace
containing the new set of extensions, and get rid of the one for the
old extensions.


But this will throw out all the old extensions and I don't want to do that
since it will require rewriting them? I just want to have the ability to
modify a few if necessary, say, for specific applications.

Lets say I override 30 types and one of those is DateTime. But for a
specific application I want to change what the extension does(say instead of
binary output it does text).. I don't want to have to reimplement all the
other types or change the name(because it might break something elsewhere).

Basically I have RawRead and RawWrite. They save a type to disk. I have
extended all the value types and working on some other types. Right now I
use ToBinary on DateTime to save it and read it to a file. Now later on I
might want to use ToString and Parse for whatever reason. Or maybe there is
a bug when I write the bits to file. Since I have no way of modifying the
extension(or removing it) I'm stuck with that unless I have the source code.
(which means there is no easy way to extend it... but maybe reflection can
help?)


Seems like a bad thing to make extensions unextendable ;/ (not sure if the
is a programmatic reason or what)
 
J

Jon Skeet [C# MVP]

Jon Slaughter said:
But this will throw out all the old extensions and I don't want to do that
since it will require rewriting them? I just want to have the ability to
modify a few if necessary, say, for specific applications.

Then you'd be well advised to keep different extensions in different
namespaces.

Personally I don't like the way extension method discovery worked - I
wish you had to specify the exact *class* to get stuff from instead of
a namespace. Basically at the moment you're well advised to keep to a
few extended types per namespace, if not just one.
Lets say I override 30 types and one of those is DateTime. But for a
specific application I want to change what the extension does(say instead of
binary output it does text).. I don't want to have to reimplement all the
other types or change the name(because it might break something elsewhere).

Basically I have RawRead and RawWrite. They save a type to disk. I have
extended all the value types and working on some other types. Right now I
use ToBinary on DateTime to save it and read it to a file. Now later on I
might want to use ToString and Parse for whatever reason. Or maybe there is
a bug when I write the bits to file. Since I have no way of modifying the
extension(or removing it) I'm stuck with that unless I have the source code.
(which means there is no easy way to extend it... but maybe reflection can
help?)

One lesson there is to keep source code!
Seems like a bad thing to make extensions unextendable ;/ (not sure if the
is a programmatic reason or what)

I can't easily think of an *elegant* way to do it, to be honest -
beyond what I suggested earlier.
 
J

Jon Slaughter

Jon Skeet said:
Then you'd be well advised to keep different extensions in different
namespaces.

Personally I don't like the way extension method discovery worked - I
wish you had to specify the exact *class* to get stuff from instead of
a namespace. Basically at the moment you're well advised to keep to a
few extended types per namespace, if not just one.


One lesson there is to keep source code!


I can't easily think of an *elegant* way to do it, to be honest -
beyond what I suggested earlier.

But I might want to distribute the code or use it in a different program
without worrying about the source code. I don't think namespaces can help
here because ultimately it still requires me to redefine all extensions.

What I mean is, suppose I have some extension to Int32 and I write an app
that uses that extension. Then I want to modify the extensions internal
workings which does not effect the apps behavior in the least bit... but
this can't be done!?!?! Why? Because I can't use the same name or I'll have
to recode all the extensions. (since you get all or nothing... unless I had
one extension per namespace ;/)

Another example:

suppose I have 20 extensions to the basic types all in the same namespace
and an app that uses them all. I want to modify the internals of just one
but still have it work with the app. Can't be done unless I recode them all
or use a different name.

Now I suppose I could replace method names in all the files but seems like
ass backwards way to do it.

I suppose it would be better to have a way to tell the compiler which
extension to use when there is a collision. This would solve the problem and
probably could be done quite easily using an attribute or something.
 
J

Jon Skeet [C# MVP]

Jon Slaughter said:
But I might want to distribute the code or use it in a different program
without worrying about the source code. I don't think namespaces can help
here because ultimately it still requires me to redefine all extensions.

What I mean is, suppose I have some extension to Int32 and I write an app
that uses that extension. Then I want to modify the extensions internal
workings which does not effect the apps behavior in the least bit... but
this can't be done!?!?! Why? Because I can't use the same name or I'll have
to recode all the extensions. (since you get all or nothing... unless I had
one extension per namespace ;/)

It sounds like really you just want to rebuild the class library with
the replaced internals. This is no different to any other peice o code
versioning - how would you do it if you wanted to replace the
implementation of a normal instance method?
 

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