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 / Interop / September 2004

Tip: Looking for answers? Try searching our database.

Default property not called using late binding in VB

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Ken Kolda - 28 Jun 2004 18:48 GMT
I have some .NET classes which I intend for possible use with VB 6 (or other
COM-compliant language). On some of my objects I have defined a default
property which takes an argument, e.g.

Dim fols as Folders
Dim s as String
Set fols = New Folders
s = fols("SomeFolder").Name

In this example, the Folders object has a default property named Item which
takes a string parameter and returns a Folder object (which, in turn, has a
Name property). The code above, which omits the explicit reference to the
Item property, works fine as long as the variables are strongly-typed. Of
course, it also works fine if you use the default property name explicitly,
even if you get rid of the strongly-typed variables, e.g.

Dim fols as Object
Dim s as String
Set fols = New Folders
s = fols.Item("SomeFolder").Name

But, if I omit the explicit reference to "Item" in the second example, I get
the error: "Wrong number of arguments or invalid property assignment".
What's annoying is that I know that for other COM objects (e.g. the
Recordset object) you can use default properties even if the object
reference isn't strongly-typed. So, I'm assuming there must be an attribute
or something else I'm leaving out of my .NET code which enables this
functionality.

Any help/suggestions would be greatly appreciated.

Thanks -
Ken
Patrick Steele [MVP] - 29 Jun 2004 22:07 GMT
> I have some .NET classes which I intend for possible use with VB 6 (or other
> COM-compliant language). On some of my objects I have defined a default
[quoted text clipped - 24 lines]
> or something else I'm leaving out of my .NET code which enables this
> functionality.

Try setting the DispId attribute on the default method to 0.

Signature

Patrick Steele
Microsoft .NET MVP
http://weblogs.asp.net/psteele

Ken Kolda - 29 Jun 2004 22:46 GMT
That's a great suggestion -- unfortunately, I've already tried it :)

Whether I use the DispId attribute or not, because the property in question
is a C# indexer it appears that regasm always mark it as the default
property whether the DispId attribute is present or not. I've verified this
by looking in the typelib -- I can see that this property has DispId of 0
whether I assign it explicitly or not. Additionally, if I look at the object
in the VB Object Browser, it shows the Item property as default. So, using
DispId in this case seems to be redundant.

I don't know if this is relevant, but the
ClassInterface(ClassInterfaceType.None) at the assembly level so that I can
define my own class interfaces for every class in my project. This has
worked just fine to this point so I've assumed that doesn't have anything to
do with the current problem.

Thanks again -
Ken

> > I have some .NET classes which I intend for possible use with VB 6 (or other
> > COM-compliant language). On some of my objects I have defined a default
[quoted text clipped - 26 lines]
>
> Try setting the DispId attribute on the default method to 0.
Patrick Steele [MVP] - 30 Jun 2004 16:17 GMT
> That's a great suggestion -- unfortunately, I've already tried it :)
>
> Whether I use the DispId attribute or not, because the property in question
> is a C# indexer it appears that regasm always mark it as the default
> property whether the DispId attribute is present or not.

Ok, wasn't sure if it would do that.  Neat!

> I don't know if this is relevant, but the
> ClassInterface(ClassInterfaceType.None) at the assembly level so that I can
> define my own class interfaces for every class in my project. This has
> worked just fine to this point so I've assumed that doesn't have anything to
> do with the current problem.

I tried to reproduce your problem and was unable.  Here's a quick
snippet of code I used.  The only difference I see (based on your
description) is that I define an interface for my .NET classes and
they'll be the default interface since I also have the ClassInterface
(ClassInterfaceType.None) attribute applied to the assembly:

using System;
using System.Collections;

namespace DispIdZero
{
    public interface IPerson
    {
        string FullName { get; set; }
    }

    public class CPerson : IPerson
    {
        private string m_Fullname = null;

        public CPerson()
        {
        }

        public string FullName
        {
            get { return m_Fullname; }
            set { m_Fullname = value; }
        }
    }

    public interface IPeople
    {
        IPerson this[string index]{ get; }
        int Count { get; }
    }

    public class CPeople : IPeople
    {
        private Hashtable m_People = new Hashtable();

        public CPeople()
        {
            IPerson p;

            p = new CPerson();
            p.FullName = "Bob Barker";
            m_People.Add("BOB", p);

            p = new CPerson();
            p.FullName = "Mike Meyers";
            m_People.Add("MIKE", p);
        }

        public IPerson this[string index]
        {
            get
            {
                return (IPerson) m_People[index];
            }
        }

        public int Count
        {
            get
            {
                return 0;
            }
        }
    }
}

Using REGASM (along with the /tlb option) I was able to get the
following VB6 code to work:

   Dim people As CPeople
   
   Set people = New CPeople
   Debug.Print people.Item("BOB").FullName
   Debug.Print people("BOB").FullName
   
   Dim op As Object
   
   Set op = New CPeople
   Debug.Print op.Item("MIKE").FullName
   Debug.Print op("MIKE").FullName

Signature

Patrick Steele
Microsoft .NET MVP
http://weblogs.asp.net/psteele

DotNetJunkies User - 16 Sep 2004 22:06 GMT
Try adding the [DispId(0)] attribute to the actual get and set methods.

---

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.