Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / February 2004

Tip: Looking for answers? Try searching our database.

Multiple put_ property accesors

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Michael Sparks - 21 Feb 2004 09:19 GMT
I am trying to accomplish something like this: (C# pseudocode)

class MySample
{
IBigObject _value;
Type _type;

public IBigObject TheBigObject
{
 get
 {
  if(_type!=null)
  {
   _value=(IBigObject)_type.GetConstructor(Type.EmptyTypes).Invoke(new
object[0]);
   _type=null;
  }
  return _value;
 }

 set(IBigObject value)
 {
  _value=value;
  _type=null;
 }

 set(Type type)
 {
  _type=type;
  _value=null;
 }
}
}

The idea is that the value of TheBigObject may never end up being consumed.
I'd like to delay construction of the object until such time.
My sample code above is simply my preference for syntactic sugar; I could of
course implement this functionality using two properties.
C# doesn't appear to support this sort of syntactic sugar, but I am
interested to know if the CLR would support it.

I dug around and found the System.Reflection.Emit.PropertyBuilder class,
which has two methods: SetGetMethod and SetGetMethod.  This is not
encouraging.  However, I also spotted the AddOtherMethod member.  Perhaps
there is hope, I thought.  Problem is, I can't find any good documentation
on AddOtherMethod, or what exactly an "other" method is supposed to be.

My question: could I use AddOtherMethod to accomplish something like this,
and if not, what is it there for?
Also, I am interested in others' opinions on whether this is a decent
approach to the problem, or if I am attempting an object-oriented faux pas
of some sort.

Thanks
Mike
Michael Sparks - 21 Feb 2004 11:41 GMT
After posting, I stumbled upon the fact that you can have two properties
with the same name.
I tried to pull that off in C#, but I think it is disallowed because C#
syntax couples the property type with the put_ accesor's parameters, and it
would not work to have two properties with the same name but different
types.

I am still curious about AddOtherMethod if anyone can shed some light on it.

> I am trying to accomplish something like this: (C# pseudocode)
>
[quoted text clipped - 51 lines]
> Thanks
> Mike
Daniel O'Connell [C# MVP] - 21 Feb 2004 19:31 GMT
> After posting, I stumbled upon the fact that you can have two properties
> with the same name.
[quoted text clipped - 6 lines]
> I am still curious about AddOtherMethod if anyone can shed some light on
> it.

In IL, return type is a valid manner of determining an overload, no such
functionality exists in C#(or VB or C++ to my knowledge, Eiffel supports
this I believe. I've been trying to figure out a simple way to add it to C#
as well). As such it is possible in IL to generate multiple properties with
the same name, but C# probably will not deal with it well(have you tested
it?).

It is also impossible to have a property with several set methods because
the CLI spec has a restriction that only one getter and one setter can exist
on a given method.

From the ECMA CLI spec:

.get specifies the getter for this property. The <typeSpec> defaults to the
current type. Only one getter may be
specified for a property. To be CLS compliant, the definition of getter
shall be marked specialname.

.set specifies the setter for this property. The <typeSpec> defaults to the
current type. Only one setter may be
specified for a property. To be CLS compliant, the definition of setter
shall be marked specialname.

.other is used to specify any other methods that this property comprises.

As for AddOtherMethod, it will add a method marked by .other. These methods
could be used by another language and associated with a property, but C# and
VB will see them as normal methods. If you were to create a language that
does what you want(allows multiple set methods), you could use
AddOtherMethod or .other in il to add the setters, although only your
language would allow you to use them like properties, other languagues would
have to call the methods explicitly.

A possible method(in IL) would be:

   .property specialname string TestProperty()
   {
.set instance void set_TestProperty(class [mscorlib]System.String)
.get instance string get_TestProperty()
.other instance void SetTestPropertyAsInt32(class [mscorlib]System.Int32)

.other instance void SetTestPropertyAsDecimal(class
[mscorlib]System.Decimal)

   }

associated with attributes could allow your C# variant, for example, to hide
SetTestPropertyAsInt32() and SetTestPropertyAsDecimal() as a property while
exposing the methods as normal methods for other languages.

However, that is a theoretical situation and impossible in standard C#.

As an offside, it would be an interesting addition, something I may play
with. Although doing it directly using set {} and get{} would be annoying,
writing seperate methods with the proper signature and associating them with
properties could be valuable, maybe(Syntax made up on the spot, method
bodies declared outside the proprty because propertys are annoying enough to
parse):

public string MyProperty
{
 get
 {
  return 1;
 }
 set
 {
  str = value;
 }
 set void SetMyPropertyAsInt32(int);
 set void SetMyPropertyAsDecimal(Decimal);
}
public void SetMyPropertyAsInt32(int x)
{

}
public void SetMyPropertyAsDecimal(Decimal x)
{
}

>> I am trying to accomplish something like this: (C# pseudocode)
>>
[quoted text clipped - 56 lines]
>> Thanks
>> Mike
Michael Sparks - 22 Feb 2004 06:51 GMT
> In IL, return type is a valid manner of determining an overload, no such
> functionality exists in C#(or VB or C++ to my knowledge, Eiffel supports
> this I believe. I've been trying to figure out a simple way to add it to C#
> as well). As such it is possible in IL to generate multiple properties with
> the same name, but C# probably will not deal with it well(have you tested
> it?).

Thanks for the reply.

I created an assembly using System.Reflection.Emit that had an overloaded
property, with one 'get' and two 'set's - both properties are of the same
type, but one 'set' takes a different type for a parameter.  When I try to
use the assembly from another C# project (either getting or setting), I get
this error:

error CS1545: Property, indexer, or event 'testprop' is not supported by the
language; try directly calling accessor methods 'mysample.get_testprop()' or
'mysample.set_testprop(int)'

Is there is a "suggestions box" for C# somewhere?
I seem to remember that this arrangement was possible with IDispatch.  I
wonder what would happen if you ran such a COM interface through tlbimp.
I'll follow up if I dig into that.

Mike
Daniel O'Connell [C# MVP] - 22 Feb 2004 07:53 GMT
>> In IL, return type is a valid manner of determining an overload, no such
>> functionality exists in C#(or VB or C++ to my knowledge, Eiffel supports
[quoted text clipped - 24 lines]
> wonder what would happen if you ran such a COM interface through tlbimp.
> I'll follow up if I dig into that.

Alot of COM interop code I see doesn't use properties, I'll find just get_
and set_ methods. I would assume that is because of that.

As for a suggestions box...there is an email(mswish@microsoft.com), although
it should be treated as one way and will probably not garner a response.
That is about the only thing I know of. Otherwise writing in the framework
and C# groups is probably your best path. The communication paths to MS
itself aren't as nice as they could be.
> Mike
Michael Sparks - 22 Feb 2004 08:07 GMT
> I created an assembly using System.Reflection.Emit that had an overloaded
> property, with one 'get' and two 'set's - both properties are of the same
[quoted text clipped - 5 lines]
> language; try directly calling accessor methods 'mysample.get_testprop()' or
> 'mysample.set_testprop(int)'

Turns out I made a mistake when generating the assembly.  When I did it
correctly, according to my intention in my previous post, here is the error
message I get:

error CS0121: The call is ambiguous between the following methods or
properties: 'mysample.testprop' and 'mysample.testprop'

I get that regarless of which accessor I try to use (get, or either of the
set's).

I also discovered that System.Reflection.Emit.PropertyBuilder *will* let you
assign multiple 'set' methods to a single property (just call SetSetMethod
more than once!), and ildasm shows them correctly.  Here is the text from
ildasm:

.property int32 testprop()
{
 .set instance void mysample::set_testprop(int32)
 .get instance int32 mysample::get_testprop()
 .set instance void mysample::set_testprop(string)
} // end of property mysample::testprop

I am able to load this assembly, and using reflection, create an instance of
the object.  This means that it must be JIT-ing correctly, so the CLR is not
enforcing the restriction you quoted from the spec.
Using reflection, I am able to call all three accessors using
Type.GetMethod().Invoke().
I can call the get_ accessor using Type.GetProperty().GetValue(), but
calling Type.GetProperty().SetValue() only works for the set_ accessor that
is declared last in the IL.

However, when trying to use this from C#, I get the error I showed in my
previous post:

error CS1545: Property, indexer, or event 'testprop' is not supported by the
language; try directly calling accessor methods 'mysample.get_testprop()' or
'mysample.set_testprop(string)'

> I seem to remember that this arrangement was possible with IDispatch.  I
> wonder what would happen if you ran such a COM interface through tlbimp.
> I'll follow up if I dig into that.

I checked on this also.  It turns out that the IDispatch interface itself is
capable of this, and it also seems that the TLB file format can express it,
but MIDL refuses to compile overloads.

So, if you had a completely IDispatch scenario, which is common with ActiveX
scripting or other pure Automation languages, you could do it.  But in that
case, there is no need for a TLB.  No TLB, no tlbimp.

Mike
Daniel O'Connell [C# MVP] - 22 Feb 2004 08:50 GMT
>> I created an assembly using System.Reflection.Emit that had an overloaded
>> property, with one 'get' and two 'set's - both properties are of the same
[quoted text clipped - 17 lines]
> error CS0121: The call is ambiguous between the following methods or
> properties: 'mysample.testprop' and 'mysample.testprop'

This is expected, property overloading isn't a feature of C#. Due to the
nature of properties, the set method's value param is expected to be the
same type as the return value. A solution could be overloading by return
type, but that has other ramifications.

> I get that regarless of which accessor I try to use (get, or either of the
> set's).
[quoted text clipped - 11 lines]
>  .set instance void mysample::set_testprop(string)
> } // end of property mysample::testprop

This seems like something that should fail, as its against the CLI spec.
Interestingly on a round trip ilasm should cut off
mysample::set_testprop(int32), it did in my earlier IL tests.

> I am able to load this assembly, and using reflection, create an instance
> of
[quoted text clipped - 16 lines]
> or
> 'mysample.set_testprop(string)'
Its unfortunate the runtime isn't respecting the spec in that manner, I
guess they left it up to compilers and such to get it right(I didn't read
the spec fully, that may have been a requirement for IL producers, not
nessecerily consumers, I'll have to check on that). I think a solution using
.other methods would be a better one, all in all. However since reflection
and languages will only use the last setter the issue isn't too important.
SetSetMethod should simply set the setter instead of adding a new one, even
the name suggests this. I'm curious if Mono duplicates this or not. I would
assume this may actulaly be a bug, I think due to the nature of the
underlying system more than anything else.

>> I seem to remember that this arrangement was possible with IDispatch.  I
>> wonder what would happen if you ran such a COM interface through tlbimp.
[quoted text clipped - 13 lines]
>
> Mike

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.