"Extension" properties?

A

Arthur Dent

Hi all, ... is there any way to use the new CompilerServices Extension
attribute with class *Properties*?

Internally properties are just implemented as a pair of functions (get/set),
aren't they? So shouldn't it be possible to create Extension Properties?

Thanks in advance,
- Arthur Dent.
 
J

Jon Skeet [C# MVP]

Arthur Dent said:
Hi all, ... is there any way to use the new CompilerServices Extension
attribute with class *Properties*?

Not at the moment.
Internally properties are just implemented as a pair of functions (get/set),
aren't they? So shouldn't it be possible to create Extension Properties?

Properties are more than just a pair of functions - they're metadata
associated with the property itself.

Basically extension properties aren't supported yet - at least not in
C#. That's not to say that'll be the case forever, but for the moment
we've only got extension methods.
 
B

Bill McCarthy

Hi Arthur,

The problem is more complex than it might first seem. A property represents
a "state" of an object, whereas methods typically indicate something is
fetched or calculated. So for extension properties you would need a state
store that is associated with an instance. Sure you could do this with a
static (Shared) dictionary of some sort, but you'd also need to ensure you
use weak references so as you don't inadvertently keep the objects alive.
 
J

Jon Skeet [C# MVP]

Bill McCarthy said:
The problem is more complex than it might first seem. A property represents
a "state" of an object, whereas methods typically indicate something is
fetched or calculated. So for extension properties you would need a state
store that is associated with an instance. Sure you could do this with a
static (Shared) dictionary of some sort, but you'd also need to ensure you
use weak references so as you don't inadvertently keep the objects alive.

No, that would be a bad thing to do - but a lot of times extension
properties would be useful even if they weren't able to store extra
state. Often they could calculate the value given the existing state.

Extension properties would also be very useful for writing fluent
interfaces.
 
B

Bill McCarthy

Hi Jon,

Jon Skeet said:
No, that would be a bad thing to do -


Right it can cause a LOT of issues.

but a lot of times extension
properties would be useful even if they weren't able to store extra
state.


Well then it is a method not a property really. A property should be
similar to a field.

Often they could calculate the value given the existing state.

Sure, but why use a property there when they can use a method ? A method is
actually more flexible as you can set a value as well as return a value with
the one method.


Extension properties would also be very useful for writing fluent
interfaces.


Really ? How so ? You can't set a value and return a value with a
property.
 
J

Jon Skeet [C# MVP]

Well then it is a method not a property really. A property should be
similar to a field.

What gives you that impression? Consider DateTime - all the properties
there are calculations based off a single field. There are plenty of
times when several properties can be calculated from a single field -
or where a particular type will override a property to always return
the same value.

The whole point of a property (as opposed to a field) is to allow the
implementation to do more than it would with a field. It could do lazy
loading from a database, for instance. The API is specified only in
terms of what the client can expect to be returned/set, not how that
is implemented.
Sure, but why use a property there when they can use a method ? A method is
actually more flexible as you can set a value as well as return a value with
the one method.

Would you really suggest that all the DateTime properties should be
methods?
Really ? How so ? You can't set a value and return a value with a
property.

Um, you don't tend to do that with fluent interfaces.

Having extension properties would mean being able to write:

var x = 2.Dollars;

instead of

var x = 2.Dollars();

for instance, or

var meetingTime = 2.Days.From.Now;
which reads somewhat better than:
var meetingTime = 2.Days().From().Now();

Jon
 
B

Bill McCarthy

Jon Skeet said:
Would you really suggest that all the DateTime properties should be
methods?


They are all read only properties so there is no benifit compared to a
method call.

Um, you don't tend to do that with fluent interfaces.


Since when ? Here, read Martin Fowler on them:
http://martinfowler.com/bliki/FluentInterface.html

To claim that fluent interfaces are only read only properties is complete
nonsense. The whole idea is you can set,fecth, calculate and read in a
chained statement.



Having extension properties would mean being able to write:

var x = 2.Dollars;

instead of

var x = 2.Dollars();

So that'd be a C# language issue requiring ()'s on methods not properties.


for instance, or

var meetingTime = 2.Days.From.Now;
which reads somewhat better than:
var meetingTime = 2.Days().From().Now();

Again, an issue in C#, not VB ;)
 
J

Jon Skeet [C# MVP]

They are all read only properties so there is no benifit compared to a
method call.

The benefit is in readability. I wouldn't expect to see many writable
extension properties, but read-only ones would be useful.
Since when ? Here, read Martin Fowler on them:http://martinfowler.com/bliki/FluentInterface.html

Okay, "don't tend to" was a bad choice of words. Let me rephrase:
there are plenty of situations using fluent interfaces where you don't
need to pass any parameters, at which point extension properties make
life more readable.
To claim that fluent interfaces are only read only properties is complete
nonsense. The whole idea is you can set,fecth, calculate and read in a
chained statement.

The idea is that you can build what you need to build in the most
readable form.
So that'd be a C# language issue requiring ()'s on methods not properties.

Well, I'd argue that's a VB issue of hiding the difference between
methods and properties, but a C# issue of not supporting extension
properties.
Again, an issue in C#, not VB ;)

Sure. It still means that extension properties are desirable as far as
I'm concerned.

Jon
 
B

Bill McCarthy

Jon Skeet said:
The benefit is in readability. I wouldn't expect to see many writable
extension properties, but read-only ones would be useful.

Again, there is no readability difference for a method compared to a
ReadOnly property, at least not in VB.

Okay, "don't tend to" was a bad choice of words. Let me rephrase:
there are plenty of situations using fluent interfaces where you don't
need to pass any parameters, at which point extension properties make
life more readable.


Let me quote to you what Martin Fowler says:
<quote>
The common convention in the curly brace world is that modifier methods are
void, which I like because it follows the principle of
CommandQuerySeparation. This convention does get in the way of a fluent
interface, so I'm inclined to suspend the convention for this case.
</quote>

So clearly, Martin is saying that "Properties" as used in C style languages
such as C#, does get in the way of a fluent interface.

The idea is that you can build what you need to build in the most
readable form.


Again, and extension method provides the same readability. If I read you
right, the issue you have is with having to have the ()'s. Well don't you
want them there considering with extension methods, and also properties, you
can get a null reference exception for the object being extended...
something you should never be able to get with properties ;)


Well, I'd argue that's a VB issue of hiding the difference between
methods and properties, but a C# issue of not supporting extension
properties.


VB gives you the choice. C# seems to be forcing you to write things you say
are less readable ;)

Sure. It still means that extension properties are desirable as far as
I'm concerned.

Or make the ()'s optional when calling extension methods.
 
J

Jon Skeet [C# MVP]

Again, there is no readability difference for a method compared to a
ReadOnly property, at least not in VB.

Sure - that doesn't stop them being useful in C# though.
Let me quote to you what Martin Fowler says:
<quote>
The common convention in the curly brace world is that modifier methods are
void, which I like because it follows the principle of
CommandQuerySeparation. This convention does get in the way of a fluent
interface, so I'm inclined to suspend the convention for this case.
</quote>

So clearly, Martin is saying that "Properties" as used in C style languages
such as C#, does get in the way of a fluent interface.

Well, I disagree for at least *some* fluent interfaces - because I'd
prefer to make the methods return new values based on the old rather
than changing the existing value. This is the way that LINQ works, for
example - you chain together many sequences, rather than changing the
existing one.

Other fluent interfaces such as StringBuilder return "this" at the end
of modifying methods like Append, but I certainly wouldn't use an
extension property to do that kind of thing. Ick! In general I prefer
immutable types where they're reasonable, and fluent interfaces work
very well with that pattern.
Again, and extension method provides the same readability. If I read you
right, the issue you have is with having to have the ()'s. Well don't you
want them there considering with extension methods, and also properties, you
can get a null reference exception for the object being extended...
something you should never be able to get with properties ;)

I don't see what bearing NullReferenceExceptions have on the matter at
all. Where's the connection between them and brackets?

And yes, it's a case of getting rid of the extra parentheses in *some*
cases.
VB gives you the choice. C# seems to be forcing you to write things you say
are less readable ;)

In this particular case, yes. It's a very specific case, however, and
in general I'm in favour of C#'s strictness here.
Or make the ()'s optional when calling extension methods.

Ick - I'd very much *not* be in favour of that. Having extension
properties (and potentially even operators) is a much cleaner and more
consistent solution.

Jon
 
B

Bill McCarthy

Jon Skeet said:
Sure - that doesn't stop them being useful in C# though.

Well if this isn't an issue for Vb, yet it is an issue for C#, then perhaps
C# should be looking at what VB does already today.
Well, I disagree for at least *some* fluent interfaces - because I'd
prefer to make the methods return new values based on the old rather
than changing the existing value.


You are talking read only properties; Martin is talking about richer fluency
including creation.

Just how big is the need for ReadOnly extension properties on immutable
types ? I think in virtually all cases you think of, you'll find that you
actually start needing to define the types, and hence can place real
properties in them.

This is the way that LINQ works, for
example - you chain together many sequences, rather than changing the
existing one.

LINQ works as extension methods, e.g Count or Sum.


Other fluent interfaces such as StringBuilder return "this" at the end
of modifying methods like Append, but I certainly wouldn't use an
extension property to do that kind of thing. Ick! In general I prefer
immutable types where they're reasonable, and fluent interfaces work
very well with that pattern.


So you want extension properties only for immutable types and (hence) only
ReadOnly properties ? This all for the sake of ommitting the ()'s right ?


I don't see what bearing NullReferenceExceptions have on the matter at
all. Where's the connection between them and brackets?


An extension method or property (if they were to exist) can be passed a null
reference as the object they are extending. Since when does it make sense
that a null object has properties and that the property getter (or setter)
would get called ??


And yes, it's a case of getting rid of the extra parentheses in *some*
cases.


Well that's the only reason so far, and so far you've also limited it to
ReadOnly and immutable types.

In this particular case, yes. It's a very specific case, however, and
in general I'm in favour of C#'s strictness here.


Why ? A property is just a wrapper for a setter and getter.
Ick - I'd very much *not* be in favour of that. Having extension
properties (and potentially even operators) is a much cleaner and more
consistent solution.

Cleaner ? You'd be adding properties that don't exist. If you serialize a
type then deserialize it, it doesn't have the same properties. That should
be enough to say it isn't clean, it's a poor fudge pretending a type has
properties when it does not. If you look at all the issues associated with
extension properties, it becomes clear they aren't clean. You have already
said you'd basically only use them for ReadOnly properties, and only on
immutable types. This just to avoid having ()'s seems to be polluting the
language if you ask me. And you need to consider the effect that then has
on the CLR and cross language interoperability. Take all these things and
weigh them up against having to add ()'s
 
J

Jon Skeet [C# MVP]

Well if this isn't an issue for Vb, yet it is an issue for C#, then perhaps
C# should be looking at what VB does already today.

I believe it should be looking at a mechanism which fits in with
everything that exists today. Extension properties are a natural
extension of where we are today - making brackets optional isn't.
You are talking read only properties; Martin is talking about richer fluency
including creation.

The properties can create objects with no problems. I don't see what
your objection is here.
Just how big is the need for ReadOnly extension properties on immutable
types ? I think in virtually all cases you think of, you'll find that you
actually start needing to define the types, and hence can place real
properties in them.

Various options with dates and times, numbers etc.

Put it this way: I've encountered cases where I'd like to use them,
and others have too (if you search for "extension properties" you'll
find others who wish to use them for fluent interfaces).
LINQ works as extension methods, e.g Count or Sum.

Yes, but the point is that those extension methods aren't modifier
methods - they don't change the object they appear to be called on,
they merely return a new one. This isn't the same as the
StringBuilder.Append type behaviour, which is what I believe Martin
was talking about in the quote that you mentioned.
So you want extension properties only for immutable types and (hence) only
ReadOnly properties ? This all for the sake of ommitting the ()'s right ?

Primarily, not necessarily "only". I certainly don't imagine that I
can foresee all possible uses.
An extension method or property (if they were to exist) can be passed a null
reference as the object they are extending.

Yes, I'm aware of that.
Since when does it make sense
that a null object has properties and that the property getter (or setter)
would get called ??

I'd guess in a similar set of situations to where it makes sense to
call a method on a null object. Where do you see the difference
between methods and properties here?
Well that's the only reason so far, and so far you've also limited it to
ReadOnly and immutable types.

In the cases I've wanted to use, yes.
Why ? A property is just a wrapper for a setter and getter.

Yes, but I believe it's good to know that that's what you're using,
rather than calling a method.

But hey, that's part of the C# philosophy.
Cleaner ? You'd be adding properties that don't exist.

In exactly the same way as methods are added which don't exist.
If you serialize a
type then deserialize it, it doesn't have the same properties.

The extension property values wouldn't be serialized, but that should
be fine because their values should only depend on *other* state.
Consider serialization as storing state, and we can't add state with
extension methods or properties.
That should
be enough to say it isn't clean, it's a poor fudge pretending a type has
properties when it does not.

Do you object to extension methods as well?
If you look at all the issues associated with
extension properties, it becomes clear they aren't clean.

Which issues? Where are they problematic in places that extension
methods aren't?
You have already
said you'd basically only use them for ReadOnly properties, and only on
immutable types.

Probably. That doesn't mean there aren't other uses - but those would
be the majority, I imagine.
This just to avoid having ()'s seems to be polluting the
language if you ask me. And you need to consider the effect that then has
on the CLR and cross language interoperability. Take all these things and
weigh them up against having to add ()'s

Why would it have *any* effect on the CLR? Extension methods don't
have any effect on the CLR, so why should extension properties? It's
all just a compile-time bit of syntactic sugar. Heck, C# could even
gain extension properties without VB understanding of being able to
generate them...

Jon
 
H

Herfried K. Wagner [MVP]

Jon Skeet said:
No, that would be a bad thing to do - but a lot of times extension
properties would be useful even if they weren't able to store extra
state. Often they could calculate the value given the existing state.

Amanda Silver of the VB team presented an 'Extends' statement in her talk
about VB's future on TechEd EMEA 2007 which served exactly this purpose:
Extension of existing types with support extra state. This concept goes far
beyond extension methods, which are only syntactic sugar.
 
B

Bill McCarthy

Herfried K. Wagner said:
Amanda Silver of the VB team presented an 'Extends' statement in her talk
about VB's future on TechEd EMEA 2007 which served exactly this purpose:
Extension of existing types with support extra state. This concept goes
far beyond extension methods, which are only syntactic sugar.

Isn't that more to do with mixins ?
 
J

Jon Skeet [C# MVP]

Isn't that more to do with mixins ?

Certainly sounds like it - different kettle of fish entirely. (And one
with significant limitations or issues, depending on what's being
proposed. I love the idea of mixins in an appropriate way, and
particularly for interfaces which just delegate to another
implementation, but I think we need to be wary of going too far.)

Jon
 
B

Bill McCarthy

Jon Skeet said:
I believe it should be looking at a mechanism which fits in with
everything that exists today. Extension properties are a natural
extension of where we are today - making brackets optional isn't.


No extension properties are not a natural extension for C#. In fact they go
against the C# rule of not allowing parameters to property gets *except* in
the case of indexers, in which case you are required ot use [] and the
property name Item is hidden.

The properties can create objects with no problems. I don't see what
your objection is here.

You're kidding me right ? The ReadOnly properties can only create a very
narrow predefined set of objects based on the public exposed state of the
object being extended. You certainly could not be adding line items to a
record.


Various options with dates and times, numbers etc.


None that require properties though ;)

Put it this way: I've encountered cases where I'd like to use them,
and others have too (if you search for "extension properties" you'll
find others who wish to use them for fluent interfaces).

Well I haven't seen them. I thought if it was a major issue they'd be well
known and well described. If you wish to present soem examples, that'd be
good, it may even further the conversation.

Yes, but the point is that those extension methods aren't modifier
methods - they don't change the object they appear to be called on,
they merely return a new one. This isn't the same as the
StringBuilder.Append type behaviour, which is what I believe Martin
was talking about in the quote that you mentioned.


I was commenting about your statement in regards to LINQ not in regards to
Martin's statements, so that wasn't the point at all ;)

Martin was talking about rich fluent interfaces, something which extension
properties in C# would NOT provide.

Primarily, not necessarily "only". I certainly don't imagine that I
can foresee all possible uses.


Extension properties with setters raise a whole heap of issues. It really
is important to step back and look at basic OO principles. They aren't
properties of the object and they could only manipulate existing public
properties. It's fundamentally wrong to present them as properties.


Yes, I'm aware of that.

So you think a null reference should have properties ?


I'd guess in a similar set of situations to where it makes sense to
call a method on a null object. Where do you see the difference
between methods and properties here?


OO 101 ;) A method is not claiming to be a property of a non existant
object.



In the cases I've wanted to use, yes.


Yes, but I believe it's good to know that that's what you're using,
rather than calling a method.

But hey, that's part of the C# philosophy.


ROFL, now I know you are kidding me. C# hides indexers from you guys
because they don't want you to create properties that take parameters.
Go-on, have a look at what get's compiled and call it from IL ;)


In exactly the same way as methods are added which don't exist.


They aren't claiming to be **properties**.

The extension property values wouldn't be serialized, but that should
be fine because their values should only depend on *other* state.


So who defines where that state is ? And how does that state get serialized
if it isn't inside the type ? And why don't the getter and setter have the
ability to opt in/opt out of xml serialization after all they are
*properties* ??? (rhetorical ;))

Consider serialization as storing state, and we can't add state with
extension methods or properties.


What ? So now you are saying that an extension property wouldn't add state ?
So if you had a setter, then the getter wouldn't return that value ?


Do you object to extension methods as well?

Of course not, they are not claiming to be **properties** of the type.

Which issues? Where are they problematic in places that extension
methods aren't?


State. Both the state of the object and the state they represent.

Probably. That doesn't mean there aren't other uses - but those would
be the majority, I imagine.


Why would it have *any* effect on the CLR? Extension methods don't
have any effect on the CLR, so why should extension properties? It's
all just a compile-time bit of syntactic sugar. Heck, C# could even
gain extension properties without VB understanding of being able to
generate them...


Well today, Vb.NET can have Shared properties that take parameters, so can
already work as extension properties mechanics would require. A languages
such as C# can't see those properties though as it only supports a single
indexer per type as it's support for properties that take parameters. It's
just another issue to consider, that kind of incompatibility versus people
having to use ()
 
B

Bill McCarthy

Jon Skeet said:
Certainly sounds like it - different kettle of fish entirely. (And one
with significant limitations or issues, depending on what's being
proposed. I love the idea of mixins in an appropriate way, and
particularly for interfaces which just delegate to another
implementation, but I think we need to be wary of going too far.)

yeh, I think mixins will be good. Naming issues will be the biggest
problems and that's where interfaces would come in handy. They don't
necessarily need to delegate out to another implementation though; they can
be self contained just as well.
 
J

Jon Skeet [C# MVP]

I believe it should be looking at a mechanism which fits in with
everything that exists today. Extension properties are a natural
extension of where we are today - making brackets optional isn't.

No extension properties are not a natural extension for C#. In fact they go
against the C# rule of not allowing parameters to property gets *except* in
the case of indexers, in which case you are required ot use [] and the
property name Item is hidden.

But at the point of *use* they don't take a parameter - they act on an
instance.
You're kidding me right ? The ReadOnly properties can only create a very
narrow predefined set of objects based on the public exposed state of the
object being extended. You certainly could not be adding line items to a
record.

Who said I'd be adding line items to a record? The example Martin
happens to give isn't the only use of fluent interfaces. In many cases
the publicly exposed state is more than enough to get to the next
value.
None that require properties though ;)

Nothing *requires* properties, but that doesn't mean there isn't an
appeal to them. Extension methods aren't *required* but they make code
easier to read.
Well I haven't seen them. I thought if it was a major issue they'd be well
known and well described. If you wish to present soem examples, that'd be
good, it may even further the conversation.

As I suggested, search for them. A search for
"extension properties" "fluent interfaces"
gets interesting hits from people such as Scott Guthrie. For instance,
from:
http://weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx

<quote>
Right now we don't support extension properties. It is something I
know the language teams are considering for the future - but for right
now you can only add methods.
</quote>

So it sounds like it's not exactly far-fetched.
I was commenting about your statement in regards to LINQ not in regards to
Martin's statements, so that wasn't the point at all ;)

Martin was talking about rich fluent interfaces, something which extension
properties in C# would NOT provide.

They would make various situations more readable than they are now.
Martin was talking about modifier methods, which are useful in some
cases but not all. I wouldn't use a property in such cases - but that
doesn't mean there's no value in them.
Extension properties with setters raise a whole heap of issues. It really
is important to step back and look at basic OO principles. They aren't
properties of the object and they could only manipulate existing public
properties. It's fundamentally wrong to present them as properties.

Not necessarily. Suppose something had a Size property, but you only
wanted to change the Width. That ends up being:

foo.Size = new Size (newWidth, foo.Size.Height);

You could easily encapsulate that in extension properties for Height
and Width. Are there potential issues with properties not being
orthogonal? Sometimes - but sometimes it makes life easier, too.
So you think a null reference should have properties ?

If it can have methods, I don't see why it shouldn't have properties.
As you keep pointing out, properties are just wrappers for methods.
What makes it okay for extension methods but not for extension
properties?
OO 101 ;) A method is not claiming to be a property of a non existant
object.

No, it's claiming to be a method acting on a non-existent object. I
don't see why that's any better or worse.
ROFL, now I know you are kidding me. C# hides indexers from you guys
because they don't want you to create properties that take parameters.
Go-on, have a look at what get's compiled and call it from IL ;)

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.
They aren't claiming to be **properties**.

They're just wrappers for methods, right? I really don't see what the
philosophical different is.
So who defines where that state is ? And how does that state get serialized
if it isn't inside the type ? And why don't the getter and setter have the
ability to opt in/opt out of xml serialization after all they are
*properties* ??? (rhetorical ;))

All the state is in the existing type. It has to be, because we can't
add state. The extension properties can add more convenient ways of
accessing the same state. As the nature of the state itself hasn't
changed, the existing serialization should work just fine.
What ? So now you are saying that an extension property wouldn't add state ?

Of course it wouldn't - none that wasn't already in the object. Where
could it store that state?
So if you had a setter, then the getter wouldn't return that value ?

Taking the Size example from earlier, the Height extension property
would return the set value because the *existing* Size state of the
object would have changed. The amount of state hasn't changed, just
the ways of accessing it.
Of course not, they are not claiming to be **properties** of the type.

No, they're claiming to be **methods** of the type despite being just
as absent from the type itself.
State. Both the state of the object and the state they represent.

The amount of state held in an instance wouldn't change. Just the ways
of accessing it.
Well today, Vb.NET can have Shared properties that take parameters, so can
already work as extension properties mechanics would require. A languages
such as C# can't see those properties though as it only supports a single
indexer per type as it's support for properties that take parameters. It's
just another issue to consider, that kind of incompatibility versus people
having to use ()

I really don't think it would be a problem. You'd need some C# syntax
to explain to the compiler that you really wanted an extension
property on a particular type, but that's all. The calling code
wouldn't look any different to normal C#.

I suspect we'll have to just agree to differ on this matter - I'm
pretty sure neither of us is actually convincing the other at all.

Jon
 
B

Bill McCarthy

Jon Skeet said:
Not necessarily. Suppose something had a Size property, but you only
wanted to change the Width. That ends up being:

foo.Size = new Size (newWidth, foo.Size.Height);

You could easily encapsulate that in extension properties for Height
and Width. Are there potential issues with properties not being
orthogonal? Sometimes - but sometimes it makes life easier, too.

Okay so let me call you out on this example. show *exactly* how extension
properties would solve that and make it easier.
 
J

Jon Skeet [C# MVP]

Okay so let me call you out on this example. show *exactly* how extension
properties would solve that and make it easier.

Setting the Height property would actually set the Size property with
a copy of the existing Size value, but with the new height. Setting
the Width property would actually set the Size property with a copy of
the existing Size value, but with the new width.

Calling code which previously had to be:

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

I know which I prefer to read :) The same is true when I'm only
interested in reading the height:

Old: Console.WriteLine (foo.Size.Height);
New: Console.WriteLine (foo.Height);

Again, it's that little bit easier to read (IMO).

Now, the disadvantage is that if people use both Width and Height when
setting both, they get the right results but in an inefficient way.

Jon
 

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