all groups > dotnet interop > june 2004 >
You're in the

dotnet interop

group:

Default property not called using late binding in VB



Default property not called using late binding in VB Ken Kolda
6/28/2004 10:48:03 AM
dotnet interop: 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



Re: Default property not called using late binding in VB Ken Kolda
6/29/2004 2:46:50 PM
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


[quoted text, click to view]

Re: Default property not called using late binding in VB Patrick Steele [MVP]
6/29/2004 5:07:29 PM
In article <eWOA9gTXEHA.384@TK2MSFTNGP10.phx.gbl>, ken.kolda@elliemae-
nospamplease.com says...
[quoted text, click to view]

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

--
Patrick Steele
Microsoft .NET MVP
Re: Default property not called using late binding in VB Patrick Steele [MVP]
6/30/2004 11:17:32 AM
In article <#uZZBLiXEHA.3012@tk2msftngp13.phx.gbl>, ken.kolda@elliemae-
nospamplease.com says...
[quoted text, click to view]

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

[quoted text, click to view]

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

--
Patrick Steele
Microsoft .NET MVP
Re: Default property not called using late binding in VB DotNetJunkies User
9/16/2004 2:06:36 PM
Try adding the [DispId(0)] attribute to the actual get and set methods.

---
Posted using Wimdows.net NntpNews Component -

AddThis Social Bookmark Button