"Extension" properties?

  • Thread starter Thread starter Arthur Dent
  • Start date Start date
Jon Skeet said:
Calling code which previously had to be:

foo.Size = new Size(newWidth, foo.Size.Height);
would then be
foo.Width = newWidth;

So that's not a fluent interface is it ? And the property is read/write, not
readonly on an immutable type. For a fluent interface, you'd need to use a
method wouldn't you ? such that you could write :
foo.SetWidth(newWidth)
which would return foo so as you could continue to set values.
 
Bill McCarthy said:
So that's not a fluent interface is it ?

No, it's not - and I never claimed it to be. You wanted an example of
how a property setter would work, and I told you - having said earlier
that for fluent interfaces I'd probably only use readonly properties.

You claimed that extension properties with setters raised "a whole heap
of issues". I've given an example to the contrary. I never claimed it
had anything to do with fluent interfaces, nor did I ever claim that
fluent interfaces would be the only use for extension properties.
And the property is read/write, not
readonly on an immutable type. For a fluent interface, you'd need to use a
method wouldn't you ? such that you could write :
foo.SetWidth(newWidth)
which would return foo so as you could continue to set values.

That's not a fluent interface in the first place though. The point
wasn't to show a fluent interface - it was to show how a writable
extension property can still make sense.
 
Jon Skeet said:
No, it's not - and I never claimed it to be. You wanted an example of
how a property setter would work, and I told you - having said earlier
that for fluent interfaces I'd probably only use readonly properties.

ah my bad. I was expecting you to provide examples of the fluent interfaces
you were talking about that you did want you implement using extension
properties. I mistakenly took the only sample you provided as that.

You claimed that extension properties with setters raised "a whole heap
of issues". I've given an example to the contrary. I never claimed it
had anything to do with fluent interfaces, nor did I ever claim that
fluent interfaces would be the only use for extension properties.

Well we can always find the few odd exceptions, but really how common are
these ? Typically any type that has a read/write Size property also has a
Height and Width property or doesn't for good reasons.


That's not a fluent interface in the first place though.


Which, you're example or mine ? Mine is, as it is returning the type after
setting a value.

The point
wasn't to show a fluent interface - it was to show how a writable
extension property can still make sense.

Sure it can, but rarely. The underlying storage has to be exposed, and the
action you are doing has to be a subset of that. That doesn't change the
fact that when there isn't already an exposed storage there's issues.

So I am still interested in the cases you say you would use extension
properties, in particular the fluent interfaces with them.
 
Jon Skeet said:
I don't need to - I'm not exactly a C# newbie. But generally, C#
doesn't give you the sort of ambiguity which VB allows. For instance,
you can't do this from C#, thank goodness:

Thread t = new Thread(...);
t.Sleep(1000);

You can in VB, although I understand it was made an optional warning/
error in VB8.

I missed this before. Yes as of VB 8 (aka 2005), IOW the last 3 years, it
has been a warning. VB doesn't hide it from you. What Vb does do is allow
you to choose to call a static method from an instant variable if you want
to. Can be quite handy as it means you can avoid repeating long type and
namespace declarations, although generally I would recommend it. The thing
is, VB gives you the choice, just like the do with the ()'s on a
parameterless method call.
 
Bill McCarthy said:
ah my bad. I was expecting you to provide examples of the fluent interfaces
you were talking about that you did want you implement using extension
properties. I mistakenly took the only sample you provided as that.

Well, I provided fluent interface examples earlier - 1.Day.From.Now
etc.

The Size example I provided was within the context of the point of the
discussion about mutation.
Well we can always find the few odd exceptions, but really how common are
these ? Typically any type that has a read/write Size property also has a
Height and Width property or doesn't for good reasons.

Often, yes - but that just shows one example of how properties can
relate to each other. It's a particularly clear one, but it's far from
unheard of to use the same expression in multiple pieces of code when
one can't change the original type.
Which, you're example or mine ? Mine is, as it is returning the type after
setting a value.

It's not what I think of as fluent. It's not something that's likely to
easily be built into a sort of sentence which is easily understandable.
There's a certain amount of personal discretion on this kind of thing
though :)
Sure it can, but rarely. The underlying storage has to be exposed, and the
action you are doing has to be a subset of that.

No, nothing about an extension property would expose or use the
underlying storage. The implementer of the original type could still
change the implementation of any methods/properties used without the
extension property breaking.
That doesn't change the
fact that when there isn't already an exposed storage there's issues.

What's the exposed storage with a Size property? Is it implemented as a
Size instance inside the type, or as a pair of integers which is built
into a size on demand? Who knows? It's an implementation detail which
*isn't* exposed just because there's a Size property.
So I am still interested in the cases you say you would use extension
properties, in particular the fluent interfaces with them.

The fluent interface side would be most relevant with a chain of
no-parameter conversions - dates and times are the most obvious
examples here. Beyond that I'd have to see where things lead - I'm
certainly not claiming to be a DSL or fluent interface expert, but I've
seen enough to be convinced that extension properties would be a
welcome addition.
 
Bill McCarthy said:
I missed this before. Yes as of VB 8 (aka 2005), IOW the last 3 years, it
has been a warning.

Is it a warning by default? I can't remember now. I guess it might
depend on whether or not the project is new or converted.
VB doesn't hide it from you.

It certainly used to though. I'm glad it doesn't now, but it's still a
good example of a choice where the benefits of providing choice are
outweighed by the downsides.
What Vb does do is allow
you to choose to call a static method from an instant variable if you want
to. Can be quite handy as it means you can avoid repeating long type and
namespace declarations, although generally I would recommend it.

If you *really* want to do that in C#, you can use a using directive to
introduce an alias. I believe that's clearer in intent than using a
variable to make a call to a static method which looks like an instance
method.
The thing is, VB gives you the choice, just like the do with the ()'s
on a parameterless method call.

And I believe some choices are not worth the problems they introduce.
The thread example is a readability nightmare. It was a mistake to
allow it in Java, and it was a mistake to allow it in VB, IMO.
 
Well, I provided fluent interface examples earlier - 1.Day.From.Now
etc.

So what exactly would From be in that example ?
Day would be a time span I presume
Now makes no sense as an extension as it wouldn't need any object to work
upon. And what if you wanted a day from any other date other than now ?
You write another extension for tomorrow, and another for
TheDayAfterTomorrow ?

somehow I don't think 1.Day.From.Now is actually a practical example.


It's not what I think of as fluent. It's not something that's likely to
easily be built into a sort of sentence which is easily understandable.
There's a certain amount of personal discretion on this kind of thing
though :)


Well I could add a pointless Then extnesion that takes T and returns T then
it can be written as :
foo.SetWidth(100).Then.SetHeight(200)

Personally I thinking adding extensions such as Then to make that supposedly
more fluent is actually the wrong idea of waht fluent interfaces is about.
It's not about trying to use english words. I think the example of your
1.Day.From.Now when properly analyzed highlights that.



No, nothing about an extension property would expose or use the
underlying storage. The implementer of the original type could still
change the implementation of any methods/properties used without the
extension property breaking.

Okay we are talking about things from different perspectives here. I was
referring tothe extensions underlyiong storage has to be exposed by the type
it is extending. Clearer now ?

What's the exposed storage with a Size property? Is it implemented as a
Size instance inside the type, or as a pair of integers which is built
into a size on demand? Who knows? It's an implementation detail which
*isn't* exposed just because there's a Size property.

You are focusing on the wrong message. What I was referring to is the Size
has to be exposed and the property you are exposing is merely a subset of
that. In practice I think this is pretty limited in value for property
sets.

The fluent interface side would be most relevant with a chain of
no-parameter conversions - dates and times are the most obvious
examples here. Beyond that I'd have to see where things lead - I'm
certainly not claiming to be a DSL or fluent interface expert, but I've
seen enough to be convinced that extension properties would be a
welcome addition.

I'm far from convinced. Seriously I am yet to see a real example. That
1.Day.From.Now does not seem realistic at all to me.
 
Jon Skeet said:
Is it a warning by default? I can't remember now. I guess it might
depend on whether or not the project is new or converted.

Not sure. I would presume so with Strict on semantics.
It certainly used to though. I'm glad it doesn't now, but it's still a
good example of a choice where the benefits of providing choice are
outweighed by the downsides.


Like extension properties when you have extension methods ;)

If you *really* want to do that in C#, you can use a using directive to
introduce an alias. I believe that's clearer in intent than using a
variable to make a call to a static method which looks like an instance
method.

Right you can alias in VB as well. But in both cases, Vb or C#, writing an
alias for a one of call is overkill really.

And I believe some choices are not worth the problems they introduce.


Yep like extension properties ;)

The thread example is a readability nightmare. It was a mistake to
allow it in Java, and it was a mistake to allow it in VB, IMO.

That's one way of looking at it. Another is in the threading sample Sleep
as a static method was a bad name choice. It probably should have been
CurrentThreadSleep
 
Bill McCarthy said:
So what exactly would From be in that example ?

Probably an intermediate type which is only useful in conjunction with
a following property.
Day would be a time span I presume

That would be reasonable.
Now makes no sense as an extension as it wouldn't need any object to work
upon. And what if you wanted a day from any other date other than now ?
You write another extension for tomorrow, and another for
TheDayAfterTomorrow ?

Well, the intermediate type could have Now, Yesterday, Tomorrow, Today
and a few other properties as perfectly normal properties. The
extension properties would be on Int32 and TimeSpan.
somehow I don't think 1.Day.From.Now is actually a practical example.

Examples like that are reasonably common in the world of fluent
interfaces - and you can't argue that the meaning isn't clear :)
Well I could add a pointless Then extnesion that takes T and returns T then
it can be written as :
foo.SetWidth(100).Then.SetHeight(200)

I wouldn't be suggesting that, certainly.
Personally I thinking adding extensions such as Then to make that supposedly
more fluent is actually the wrong idea of waht fluent interfaces is about.
It's not about trying to use english words. I think the example of your
1.Day.From.Now when properly analyzed highlights that.

Whereas I clearly think the reverse :)

I think fluent interfaces have moved on from the original restrictive
"always return the original context" sense, to mean a style of
programming similar to a DSL, but within the syntax of an existing
language.

Mocking is a great example of fluent interfaces - many mocking APIs are
designed with fluent interfaces so you can read a constraint out loud
and get a good sense of what's being demanded.
Okay we are talking about things from different perspectives here. I was
referring tothe extensions underlyiong storage has to be exposed by the type
it is extending. Clearer now ?

Um, not really. Nothing has to reveal whether it's storing the data in
a single field, combined fields, a database etc. That's what I consider
to be "underlying storage". Yes, the original type has to expose the
state in some form or other, but that's to be expected.

When designing a type, you don't always know how people will use it -
particularly if you're designing something like the .NET framework
itself. Even if you knew what each different use would find beneficial
you might not want to include it all - it could make the API horrific.
However, for a particular use, it may well make sense to expose some
state in a different form from the general purpose use.
You are focusing on the wrong message. What I was referring to is the Size
has to be exposed and the property you are exposing is merely a subset of
that. In practice I think this is pretty limited in value for property
sets.

I think we probably differ in terms of our understanding of "underlying
storage".
I'm far from convinced. Seriously I am yet to see a real example. That
1.Day.From.Now does not seem realistic at all to me.

Why not? Do you never want to express that? Do you find it less
readable than DateTime.Now.AddDays(1)? I know I prefer the fluent form
- so what stops it from being realistic?
 
Bill McCarthy said:
Not sure. I would presume so with Strict on semantics.


Like extension properties when you have extension methods ;)

Except I haven't seen any actual downsides being introduced by you.
Yes, there'd need to be some extension to C# syntax, but that's about
all I can think of. I don't see why it's conceptually such a problem.
Right you can alias in VB as well. But in both cases, Vb or C#, writing an
alias for a one of call is overkill really.

Well yes - but it can be useful when you need to make a call
repeatedly. Java has an interesting approach where you can import
static members, so after something like (my Java is rusty)

static import java.lang.Math.*;

you can write

double x = sqrt(PI*2);

It's good when used *very sparingly*.
That's one way of looking at it. Another is in the threading sample Sleep
as a static method was a bad name choice. It probably should have been
CurrentThreadSleep

Nah, I don't buy it. When you make it clear that you're not calling it
on a particular thread, the *only* thread that it could refer to is the
current one. I wish Thread.CurrentThread were called Thread.Current
though, and Thread.CurrentCulture were called Thread.Culture. It's a
pain when you've got:

Thread.CurrentThread.CurrentCulture ...

Ick. I'd prefer:

Thread.Current.Culture
 
Jon Skeet said:
Well yes - but it can be useful when you need to make a call
repeatedly. Java has an interesting approach where you can import
static members, so after something like (my Java is rusty)

static import java.lang.Math.*;

you can write

double x = sqrt(PI*2);

It's good when used *very sparingly*.

You can actually do that in VB too:

\\\
Imports System.Math
....
Dim x As Double = Sqrt(PI * 2)
///
 
Jon Skeet said:
Probably an intermediate type which is only useful in conjunction with
a following property.

Huh ? It does what exactly to the Day timespan value ?

So we can have:

var x = 1.Day.From;

then later someone writes:

var dt = x.Now;

looks very bad to me indeed.


That would be reasonable.


Well, the intermediate type could have Now, Yesterday, Tomorrow, Today
and a few other properties as perfectly normal properties.


You still didn't answer as to what if you wanted a different date other than
those limited selection ? It falls down pretty quickly really.
And what exactly is Today compared to now when on a From return type ?
Would 1.Day.From.Today be different from 1.Day.From.Now ?




Examples like that are reasonably common in the world of fluent
interfaces - and you can't argue that the meaning isn't clear :)


Not that I've seen. You got any references/links ?

I would have expected at best 1.Day.FromNow and 1.Day.BeforeNow



I wouldn't be suggesting that, certainly.


LOL. Yet you were happy with From that did nothing. Strange.

Whereas I clearly think the reverse :)


clearly ;)

I think fluent interfaces have moved on from the original restrictive
"always return the original context" sense, to mean a style of
programming similar to a DSL, but within the syntax of an existing
language.


In the case of setting properties you return the original item. Likewise
when you add an item, you usually return the added item. So for the example
of SetWidth, you could potentially return a boolean, the width or the item.
Returning the item is the less restrictive and hence the most fluent
approach.

Mocking is a great example of fluent interfaces - many mocking APIs are
designed with fluent interfaces so you can read a constraint out loud
and get a good sense of what's being demanded.

Right and they'd typically be methods, right.

Um, not really. Nothing has to reveal whether it's storing the data in
a single field, combined fields, a database etc. That's what I consider
to be "underlying storage". Yes, the original type has to expose the
state in some form or other, but that's to be expected.


The underlying storage for a property is the storage mechanism (not
necessarily state) for that property is it not ? So the type you are
extending has to expose suitable storage for your extension property.

You seem to be twisting what I am saying and getting away from the point
which was when there isn't an exposed suitable storage on the underlying
type, then the extension property has some serious issues.

When designing a type, you don't always know how people will use it -
particularly if you're designing something like the .NET framework
itself. Even if you knew what each different use would find beneficial
you might not want to include it all - it could make the API horrific.
However, for a particular use, it may well make sense to expose some
state in a different form from the general purpose use.


I think that's very rare in reality.

I think we probably differ in terms of our understanding of "underlying
storage".


Clearly. You seem to view "underlying storage" as the backing fields when a
property is inside a type, yet for extension properties, you view it as the
private fields the extension couldn't get to. That doesn't make sense ot
me. The underlying storage for a property is where it writes and reads
from.

Why not? Do you never want to express that? Do you find it less
readable than DateTime.Now.AddDays(1)? I know I prefer the fluent form
- so what stops it from being realistic?

First and foremost I would typically have a date to which I want to add one
day. 1.Day.From.Now isn't going to help when I want to do a variable date
is it ? Like 1 day before your birthday. It becomes too limited, and as
such ends up creating more duplication, and hence more code maintenance.
Why would I want to take on the bloat and maintenance issues, when elsewhere
I am still going to be writing customer.Birthday.AddDays(-1)
 
Jon Skeet said:
Except I haven't seen any actual downsides being introduced by you.
Yes, there'd need to be some extension to C# syntax, but that's about
all I can think of. I don't see why it's conceptually such a problem.


Well I have listed them, so if you haven't seen them I can only suggest an
optometrist. The biggest single issue is they are not properties of the
type.

Well yes - but it can be useful when you need to make a call
repeatedly. Java has an interesting approach where you can import
static members, so after something like (my Java is rusty)

static import java.lang.Math.*;

you can write

double x = sqrt(PI*2);

It's good when used *very sparingly*.


Yes VB has this too.


Nah, I don't buy it. When you make it clear that you're not calling it
on a particular thread, the *only* thread that it could refer to is the
current one. I wish Thread.CurrentThread were called Thread.Current
though, and Thread.CurrentCulture were called Thread.Culture. It's a
pain when you've got:

Thread.CurrentThread.CurrentCulture ...

Ick. I'd prefer:

Thread.Current.Culture

But hang on, didn't you just talk about aliases and type imports. Surely in
that light you can see the need for clear names on static methods ??
 
Bill McCarthy said:
Huh ? It does what exactly to the Day timespan value ?

Remembers it.
So we can have:

var x = 1.Day.From;

then later someone writes:

var dt = x.Now;

looks very bad to me indeed.

Patient: Doctor, it hurts when I do this (hits head)
Doctor: Well don't do that then

Seriously, fluent interfaces sometimes involve intermediate types which
indeed don't make sense on their own, outside the fluent interface
expression.
You still didn't answer as to what if you wanted a different date other than
those limited selection ? It falls down pretty quickly really.
And what exactly is Today compared to now when on a From return type ?
Would 1.Day.From.Today be different from 1.Day.From.Now ?

1.Day.From.Today would be the next midnight.
1.Day.From.Now would be this time tomorrow.
Not that I've seen. You got any references/links ?

In Groovy:
http://developers.sun.com/learning/javaoneonline/2007/pdf/TS-1589.pdf
http://groovy.codehaus.org/Google+Data+Support

C# 3 acting like Ruby:
http://blog.troyd.net/PermaLink,guid,c4d8233b-77f4-4660-91a9-
8ea71cd358c7.aspx
I would have expected at best 1.Day.FromNow and 1.Day.BeforeNow

Can't say I like those much personally, although the Sun/Thoughtworks
paper uses something similar.
LOL. Yet you were happy with From that did nothing. Strange.

True. I wouldn't like to say exactly why, but it's just a gut feeling.

In the case of setting properties you return the original item. Likewise
when you add an item, you usually return the added item.

The added item, or the collection it's been added to? The latter
allows:

x.Add(new Foo())
.Add(new Bar())
.Add(...)
So for the example
of SetWidth, you could potentially return a boolean, the width or the item.
Returning the item is the less restrictive and hence the most fluent
approach.

I see your point there. An alternative in the world of immutable
objects would be to return a new object equal to the previous one
except with a different width.
Right and they'd typically be methods, right.

In many cases, yes - but I can imagine cases where it would be
reasonable to use properties instead.
The underlying storage for a property is the storage mechanism (not
necessarily state) for that property is it not ? So the type you are
extending has to expose suitable storage for your extension property.

No, I'd say it has to allow the state to be mutated appropriately. It
doesn't have to expose the nature of the storage (field, database etc).
You seem to be twisting what I am saying and getting away from the point
which was when there isn't an exposed suitable storage on the underlying
type, then the extension property has some serious issues.

I can't help it if my understanding of "underlying storage" appears to
be radically different to yours :)
I think that's very rare in reality.

Again, I'm sure we'll have to agree to differ. (Is anyone else reading
at this point?)
Clearly. You seem to view "underlying storage" as the backing fields when a
property is inside a type, yet for extension properties, you view it as the
private fields the extension couldn't get to. That doesn't make sense ot
me. The underlying storage for a property is where it writes and reads
from.

Okay, using your definition the underlying storage of the original
exposed property is the field (or whatever) then, right? I claim that
you can write an extension property without knowing or caring that the
original type happens to use a field. The original type doesn't need to
expose its underlying storage - it needs to expose a storage interface,
whether that's through properties or methods.
First and foremost I would typically have a date to which I want to add one
day. 1.Day.From.Now isn't going to help when I want to do a variable date
is it ? Like 1 day before your birthday. It becomes too limited, and as
such ends up creating more duplication, and hence more code maintenance.
Why would I want to take on the bloat and maintenance issues, when elsewhere
I am still going to be writing customer.Birthday.AddDays(-1)

Where you've got a particular date, certainly use that date.

<shrugs>

If you don't want to use extension properties, I'm certainly not going
to try to twist your arm into doing so. But don't be surprised if they
appear in a future version of C# (or VB, or other languages).
 
Bill McCarthy said:
Well I have listed them, so if you haven't seen them I can only suggest an
optometrist. The biggest single issue is they are not properties of the
type.

Every time you've listed them, I've indicated why I don't think they're
relevant or downsides.

But hang on, didn't you just talk about aliases and type imports. Surely in
that light you can see the need for clear names on static methods ??

Aliases should only be used when they don't obscure the meaning. Who's
going to alias Thread, after all?

Would you say that String.Join() should be called String.JoinStrings()
just in case someone creates an alias which makes it sound like it's
joining together something completely different?
 
Jon Skeet said:
Remembers it.


So that'd make it a method that stores the value in a new type, not a
property of the original type.

Patient: Doctor, it hurts when I do this (hits head)
Doctor: Well don't do that then


LOL. Weren't you complaining before about t.Sleep, and now you go and
design an even worse API, then say well don't use it that way. Great
inconsistency in your argument.

Seriously, fluent interfaces sometimes involve intermediate types which
indeed don't make sense on their own, outside the fluent interface
expression.

First, in that case those types are not a property of the original type, so
a method is more appropiate. Second it is bad desing and goe aginst
standard naming and type practices.

Second, what you are basically doing with From the types and it's Now and
Today properties is saying a Leg has a Chair and a Table and a Human
property. That's wrong.






Avoids intermediate types.

yes, when someone takes a good thing too far ;)


uses methods ;) (and no intermediatry type)

Can't say I like those much personally, although the Sun/Thoughtworks
paper uses something similar.


Well they are the same as in the first and third link you provided, and they
don't suffer from the issues an intermediary type does.
The problem with the intermediary type is obvious, and you are contradicting
yourself as to your arguments over t.Sleep. Bad APi is bad API. Saying you
can only use it this way, yet exposing a type as a property and then saying
don't make a reference to that is silly.

*If* from was a method, and it was marked as must be chained or similar then
the 1.Day.From.Now might make sense. From is not a property of a timespan,
and should not be presented as such simply because you want to avoid the
()'s. And it certainly should not be able to be used unchained. I think if
you want "fluent" language constructs, you also have to have the appropriate
rules of grammar that don't allow broken sentences, and where *verbs*
(methods) are not confused with *nouns* (properties)



True. I wouldn't like to say exactly why, but it's just a gut feeling.

Again, inconsistent rules of grammar ;)


The added item, or the collection it's been added to? The latter
allows:

x.Add(new Foo())
.Add(new Bar())
.Add(...)


in the case of Add, I would argue the item added as you often return extra
information such as index. The convention today is mroe oten than not to do
that, so returning the container would contradict existing API.

For the above example, I don't think .Add(....).Add(...) is really clear as
to whether the adding is to the item jusut added or the parent. I would
avoid this, in favour of an AddItems call.


I see your point there. An alternative in the world of immutable
objects would be to return a new object equal to the previous one
except with a different width.

Yeh you'd have to, eg: "hello".Add(" world"). ....

Now in this case, the case of an immutable object, neither the original item
or the item added are actually the return value, so you return a new object
with the value of both.


In many cases, yes - but I can imagine cases where it would be
reasonable to use properties instead.


hmmm.... i think the value of properties is definetly not in any fluent
interface. Fowler seems to agree on that. For fluent interfaces methods
make more sense, and avoid situations where a leg has a table and a chair
property ;)


No, I'd say it has to allow the state to be mutated appropriately. It
doesn't have to expose the nature of the storage (field, database etc).

I disagree. For it to be a property extension, it needs to be backed as
such by the type being extended, otherwise it isn't a property.

I can't help it if my understanding of "underlying storage" appears to
be radically different to yours :)

Well you can if you try ;)
Again, I'm sure we'll have to agree to differ. (Is anyone else reading
at this point?)



Okay, using your definition the underlying storage of the original
exposed property is the field (or whatever) then, right?
correct


I claim that
you can write an extension property without knowing or caring that the
original type happens to use a field.

huh ? Again you are going from the extension property and ***its*** backing
storage, and somehow equating that to a private field in the type being
exposed. Let me make this simple for you. Let's say you have an Int16, and
you give it an Int32Value property. As the Int16 does not provide any
storage mechanism for the entire Int32 you'll get overflow exceptions. So
the type being extending has to expose a value or values that serve as the
backing store for your extension property. This isn't rocket surgery ;)


The original type doesn't need to
expose its underlying storage - it needs to expose a storage interface,
whether that's through properties or methods.

Right. It needs to provide the underlying storage for your extension
property.

Where you've got a particular date, certainly use that date.


The point I am making is that fluent languages

<shrugs>

If you don't want to use extension properties,


Again, fluent interfaces don't require extension properties. That doesn't
mean extension properties don't have some usage. I think the best example is
in a property set syntax. You're arguments have been read only, and fluent
interfaces, and on that I disagree. I believe the example of 1.Day.From
highlights that these should not be properties. Instead you need to be
looking at grammar rules.

I'm certainly not going
to try to twist your arm into doing so. But don't be surprised if they
appear in a future version of C# (or VB, or other languages).

Would it upset you if I told you they are in fact already in VB ;)
 
Jon Skeet said:
Every time you've listed them, I've indicated why I don't think they're
relevant or downsides.


Oh so know you are sayign you have seen them, just you disagree ;)

Aliases should only be used when they don't obscure the meaning. Who's
going to alias Thread, after all?

Would you say that String.Join() should be called String.JoinStrings()
just in case someone creates an alias which makes it sound like it's
joining together something completely different?

If I write:

Sleep(somevar)

what does that tell you ?

If I write

Dim x = Join(var1,var2)

does that require anymore information ? I think the two are very different.
Sleep should be CurrentThreadSleep
 
Hi,

I see one question from Arthur and then a long messagethread with only
MVP's.

For those who think that Microsoft did not, there is by Microsoft created
for MVP's a closed newsgroup for dotnet to do this kind of discussions
between MVP's from different program language signature.

Cor
 
Why? there's nothing we are discussing that is under NDA, nor does this
discussion preclude any member of the public. I'd suggest if you don't wish
to be involved in the discussion, then simply don't. Please don't be
telling people what they can and cannot discuss here. Save that for your
lounge room ;)
 
Cor Ligthert said:
I see one question from Arthur and then a long messagethread with only
MVP's.

For those who think that Microsoft did not, there is by Microsoft created
for MVP's a closed newsgroup for dotnet to do this kind of discussions
between MVP's from different program language signature.

I personally see nothing wrong with a thread which happens to only
include MVPs. Any non-MVP could jump in at any time, no problem.

However, I'm pretty sure Bill and I will never see eye to eye on this,
and I don't think further discussion will actually help. That's why I'm
not replying to the posts any further - I'm afraid I don't have any
more time to waste on a discussion which isn't really going anywhere.
 
Back
Top