Bracketed types

  • Thread starter Thread starter Mike
  • Start date Start date
M

Mike

Can someone explain why/when someone would use a type with square
brackets?

For example

im myArr As [String]() = {"1", "2", "3"}
vs
im myArr As String() = {"1", "2", "3"}

Whats the difference?

--
 
Mike,

Mostly it has not sense and can even give wrong results.

The brackets are meant that if you have created your own class string (which
is to inside the brackets)
Can use that one.

In that way you can make from the [String] by instance a combobox.

But in my idea only a fool will use that.

You see this often in the first VB Net samples as they are made by C++
writers.

(And it makes your code of course very sophisticated (in a way I don't
like))

Cor
 
Mike,

Mostly it has not sense and can even give wrong results.

The brackets are meant that if you have created your own class string (which
is to inside the brackets)
Can use that one.

In that way you can make from the [String] by instance a combobox.

But in my idea only a fool will use that.

You see this often in the first VB Net samples as they are made by C++
writers.

(And it makes your code of course very sophisticated (in a way I don't
like))

Cor
 
Mike said:
Can someone explain why/when someone would use a type with square
brackets?

For example

im myArr As [String]() = {"1", "2", "3"}
vs
im myArr As String() = {"1", "2", "3"}

Whats the difference?

In the sample above, it doesn't make a difference. The brackets around a
keyword ('String' is actually a keyword) remove the keyword semantics.
Consequently it's possible to use the keyswords as identifiers by
surrounding them with brackets:

\\\
Dim [Next] As Foo
///
 
Mike said:
Can someone explain why/when someone would use a type with square
brackets?

For example

im myArr As [String]() = {"1", "2", "3"}
vs
im myArr As String() = {"1", "2", "3"}

Whats the difference?

In the sample above, it doesn't make a difference. The brackets around a
keyword ('String' is actually a keyword) remove the keyword semantics.
Consequently it's possible to use the keyswords as identifiers by
surrounding them with brackets:

\\\
Dim [Next] As Foo
///
 
Herfried said:
Mike said:
Can someone explain why/when someone would use a type with square
brackets?

For example

dim myArr As [String]() = {"1", "2", "3"}
vs
dim myArr As String() = {"1", "2", "3"}

Whats the difference?

In the sample above, it doesn't make a difference. The brackets around
a keyword ('String' is actually a keyword) remove the keyword semantics.
Consequently it's possible to use the keyswords as identifiers by
surrounding them with brackets:

\\\
Dim [Next] As Foo
///

I think I see. So basically, its nothing more than to help one not
confuse the mixing of a variable name as keywords or type, i.e.

Dim string as STRING < --- compiler error
dim [String] as String
Dim [random] As New Random(2000)

or

Dim myClass As MyClass

which compiles, but it will help to bracket it to make it more understood:

Dim [myClass] As MyClass

Right?

I've been doing "generic" types more, like in this function to convert
any object or structure field members to XML

Function FieldsToXML(Of T)(ByVal obj As T) As String

Would it be better to do?

Function MsgHeaderToXML(Of [T])(ByVal Obj As [T]) As String

Just to make it easier to understand it is a type?

--
 
Herfried said:
Mike said:
Can someone explain why/when someone would use a type with square
brackets?

For example

dim myArr As [String]() = {"1", "2", "3"}
vs
dim myArr As String() = {"1", "2", "3"}

Whats the difference?

In the sample above, it doesn't make a difference. The brackets around
a keyword ('String' is actually a keyword) remove the keyword semantics.
Consequently it's possible to use the keyswords as identifiers by
surrounding them with brackets:

\\\
Dim [Next] As Foo
///

I think I see. So basically, its nothing more than to help one not
confuse the mixing of a variable name as keywords or type, i.e.

Dim string as STRING < --- compiler error
dim [String] as String
Dim [random] As New Random(2000)

or

Dim myClass As MyClass

which compiles, but it will help to bracket it to make it more understood:

Dim [myClass] As MyClass

Right?

I've been doing "generic" types more, like in this function to convert
any object or structure field members to XML

Function FieldsToXML(Of T)(ByVal obj As T) As String

Would it be better to do?

Function MsgHeaderToXML(Of [T])(ByVal Obj As [T]) As String

Just to make it easier to understand it is a type?

--
 
Mike said:
I think I see. So basically, its nothing more than to help one not
confuse the mixing of a variable name as keywords or type, i.e.

Dim string as STRING < --- compiler error
dim [String] as String
Dim [random] As New Random(2000)

Random is not a keyword, therefore

Dim random As New Random(2000)

works also.
or

Dim myClass As MyClass

which compiles,

Does not compile here because myClass is a keyword.

I've been doing "generic" types more, like in this function to convert
any object or structure field members to XML

Function FieldsToXML(Of T)(ByVal obj As T) As String

Would it be better to do?

Function MsgHeaderToXML(Of [T])(ByVal Obj As [T]) As String

Just to make it easier to understand it is a type?

No, the compiler knows that it's a type even without the brackets. :-) The
brackets enable you to use identifieres that are (reserved) keywords. That's
all. If the identifier is not a keyword, it is not necessary to use
brackets. It doesn't hurt but it's as useful as writing

a = (((((1+2)))))

Works also. ;-)


Armin
 
Mike said:
I think I see. So basically, its nothing more than to help one not
confuse the mixing of a variable name as keywords or type, i.e.

Dim string as STRING < --- compiler error
dim [String] as String
Dim [random] As New Random(2000)

Random is not a keyword, therefore

Dim random As New Random(2000)

works also.
or

Dim myClass As MyClass

which compiles,

Does not compile here because myClass is a keyword.

I've been doing "generic" types more, like in this function to convert
any object or structure field members to XML

Function FieldsToXML(Of T)(ByVal obj As T) As String

Would it be better to do?

Function MsgHeaderToXML(Of [T])(ByVal Obj As [T]) As String

Just to make it easier to understand it is a type?

No, the compiler knows that it's a type even without the brackets. :-) The
brackets enable you to use identifieres that are (reserved) keywords. That's
all. If the identifier is not a keyword, it is not necessary to use
brackets. It doesn't hurt but it's as useful as writing

a = (((((1+2)))))

Works also. ;-)


Armin
 
Armin said:
Mike said:
I think I see. So basically, its nothing more than to help one not
confuse the mixing of a variable name as keywords or type, i.e.

Dim string as STRING < --- compiler error
dim [String] as String
Dim [random] As New Random(2000)

Random is not a keyword, therefore

Dim random As New Random(2000)

works also.
or

Dim myClass As MyClass

which compiles,

Does not compile here because myClass is a keyword.

hmmm, then I don't yet understand. I said that because I tried this:

imports Wildcat.Net.Server

...
Dim wcserverapi As WcServerAPI
Dim ni1 As WcServerAPI.TwcNodeInfo
Dim ni2 As [WcServerAPI].TwcNodeInfo

WcServerAPI is a class in my wildcat.net.server.dll

It all compiled. I understand the compiler (the compiler knows <g>) is
using the CLASS WcServerAPI for ni1 and ni2 types. But you now also
have an valid instance of the class object in wcserverapi.

If I understand brackets, it would be better for me, the human, for
readability, if I wanted to do this this way:

Dim [wcserverapi] As WcServerAPI
Dim ni1 As WcServerAPI.TwcNodeInfo
Dim ni2 As WcServerAPI.TwcNodeInfo

Would be more "readability" so when I see and use [wcserverapi] I
would be referring to the variable, and not the class.

Is that correct?

--
 
Armin said:
Mike said:
I think I see. So basically, its nothing more than to help one not
confuse the mixing of a variable name as keywords or type, i.e.

Dim string as STRING < --- compiler error
dim [String] as String
Dim [random] As New Random(2000)

Random is not a keyword, therefore

Dim random As New Random(2000)

works also.
or

Dim myClass As MyClass

which compiles,

Does not compile here because myClass is a keyword.

hmmm, then I don't yet understand. I said that because I tried this:

imports Wildcat.Net.Server

...
Dim wcserverapi As WcServerAPI
Dim ni1 As WcServerAPI.TwcNodeInfo
Dim ni2 As [WcServerAPI].TwcNodeInfo

WcServerAPI is a class in my wildcat.net.server.dll

It all compiled. I understand the compiler (the compiler knows <g>) is
using the CLASS WcServerAPI for ni1 and ni2 types. But you now also
have an valid instance of the class object in wcserverapi.

If I understand brackets, it would be better for me, the human, for
readability, if I wanted to do this this way:

Dim [wcserverapi] As WcServerAPI
Dim ni1 As WcServerAPI.TwcNodeInfo
Dim ni2 As WcServerAPI.TwcNodeInfo

Would be more "readability" so when I see and use [wcserverapi] I
would be referring to the variable, and not the class.

Is that correct?

--
 
Mike said:
Armin said:
Mike said:
I think I see. So basically, its nothing more than to help one not
confuse the mixing of a variable name as keywords or type, i.e.

Dim string as STRING < --- compiler error
dim [String] as String
Dim [random] As New Random(2000)

Random is not a keyword, therefore

Dim random As New Random(2000)

works also.
or

Dim myClass As MyClass

which compiles,

Does not compile here because myClass is a keyword.

hmmm, then I don't yet understand. I said that because I tried this:

imports Wildcat.Net.Server

...
Dim wcserverapi As WcServerAPI
Dim ni1 As WcServerAPI.TwcNodeInfo
Dim ni2 As [WcServerAPI].TwcNodeInfo

WcServerAPI is a class in my wildcat.net.server.dll

It all compiled. I understand the compiler (the compiler knows <g>) is
using the CLASS WcServerAPI for ni1 and ni2 types. But you now also
have an valid instance of the class object in wcserverapi.

If I understand brackets, it would be better for me, the human, for
readability, if I wanted to do this this way:

Dim [wcserverapi] As WcServerAPI
Dim ni1 As WcServerAPI.TwcNodeInfo
Dim ni2 As WcServerAPI.TwcNodeInfo

Would be more "readability" so when I see and use [wcserverapi] I
would be referring to the variable, and not the class.

Is that correct?

No, readability is not an issue at all when using the brackets. It wouldn't
help anyway, because it is not possible to distinguish between the variable
name and the class name by using brackets or not. This compiles w/o a
problem:

Dim Form1 As Form1

Form1 = New Form1
Form1 = New [Form1]
[Form1] = New Form1
[Form1] = New [Form1]

The brackets don't matter. In addition, you could combine the 4 assignments
with any of these declarations:

Dim Form1 As Form1
Dim Form1 As [Form1]
Dim [Form1] As Form1
Dim [Form1] As [Form1]

Everything works because everything the brackets do is: not hurt. ;)

The _only_ reason to use them is to use a keyword as an identifier, be it a
class name or a variable name. You can even reduce these cases by those that
are unambigous for the compiler:

Public Class Form1

Public [String] As String

Private Sub Test

Me.String = "abc" 'works!

End Sub

End Class

It works because there is never a keyword after the dot.

BTW, what do you think is the name of the field? Is it "[String]" or is it
"String"? I've looked at the IL code and it says:

.field public string String

So, the brackets are _only_ there for the compiler to be able to distinguish
between an identifier and a keyword in it's first, lexical, compilation
pass. The brackets don't belong to the identifier itself, i.e. they are
removed.


Armin
 
Mike said:
Armin said:
Mike said:
I think I see. So basically, its nothing more than to help one not
confuse the mixing of a variable name as keywords or type, i.e.

Dim string as STRING < --- compiler error
dim [String] as String
Dim [random] As New Random(2000)

Random is not a keyword, therefore

Dim random As New Random(2000)

works also.
or

Dim myClass As MyClass

which compiles,

Does not compile here because myClass is a keyword.

hmmm, then I don't yet understand. I said that because I tried this:

imports Wildcat.Net.Server

...
Dim wcserverapi As WcServerAPI
Dim ni1 As WcServerAPI.TwcNodeInfo
Dim ni2 As [WcServerAPI].TwcNodeInfo

WcServerAPI is a class in my wildcat.net.server.dll

It all compiled. I understand the compiler (the compiler knows <g>) is
using the CLASS WcServerAPI for ni1 and ni2 types. But you now also
have an valid instance of the class object in wcserverapi.

If I understand brackets, it would be better for me, the human, for
readability, if I wanted to do this this way:

Dim [wcserverapi] As WcServerAPI
Dim ni1 As WcServerAPI.TwcNodeInfo
Dim ni2 As WcServerAPI.TwcNodeInfo

Would be more "readability" so when I see and use [wcserverapi] I
would be referring to the variable, and not the class.

Is that correct?

No, readability is not an issue at all when using the brackets. It wouldn't
help anyway, because it is not possible to distinguish between the variable
name and the class name by using brackets or not. This compiles w/o a
problem:

Dim Form1 As Form1

Form1 = New Form1
Form1 = New [Form1]
[Form1] = New Form1
[Form1] = New [Form1]

The brackets don't matter. In addition, you could combine the 4 assignments
with any of these declarations:

Dim Form1 As Form1
Dim Form1 As [Form1]
Dim [Form1] As Form1
Dim [Form1] As [Form1]

Everything works because everything the brackets do is: not hurt. ;)

The _only_ reason to use them is to use a keyword as an identifier, be it a
class name or a variable name. You can even reduce these cases by those that
are unambigous for the compiler:

Public Class Form1

Public [String] As String

Private Sub Test

Me.String = "abc" 'works!

End Sub

End Class

It works because there is never a keyword after the dot.

BTW, what do you think is the name of the field? Is it "[String]" or is it
"String"? I've looked at the IL code and it says:

.field public string String

So, the brackets are _only_ there for the compiler to be able to distinguish
between an identifier and a keyword in it's first, lexical, compilation
pass. The brackets don't belong to the identifier itself, i.e. they are
removed.


Armin
 
Armin said:
It works because there is never a keyword after the dot.

BTW, what do you think is the name of the field? Is it "[String]" or is it
"String"? I've looked at the IL code and it says:

.field public string String

So, the brackets are _only_ there for the compiler to be able to
distinguish between an identifier and a keyword in it's first, lexical,
compilation pass. The brackets don't belong to the identifier itself,
i.e. they are removed.

Correct. I appreciate taking it to a levels I can grasp. :-)

Thanks Armin for being patience in my venture to understand VB.NET
semantics.

You see, this is important for a person like myself coming from a
C/C++ world where hungarian notations and lower/upper case matters. It
is fundamental in the readability and undertanding of APIs and
libraries. So not to argue, I have to have a small nit with you that
I do think its about code readability and developer semantics.

For example, when one sees an traditional WIN32 API function such as

BOOL xyz(LPCSTR a, LPVOID b)

you know right away that is a constant (byval) long pointer to a null
terminated string and a long pointer to a untyped variable. Like
wise, a Hungarian prefix is well understood by veteran C people.

But in regard to VB.NET brackets, this is common practice in C/C++
(and I guess C# too), where case is very important as you know:

TYPE_NAME type_name

ie.

HANDLE handle;
PHANDLE phandle;

From a code readability, when you see usages of type_name (lower
case), in the developers' or code readers' mind, they instantly know
it a variable of type TYPE_NAME

So I do think its about code readability and semantics because one
side would say that is a bad idea and another would say its not.

But if case is not a factor, then it can viewed as poor. The debates
on this has long been argued so lets do ourselves a favor and not
repeat what is better but I do wish to know what is recommended for
VB.NET.

In VB.NET, as you note, it doesn't matter because the compiler knows,
and also Intellisense seems to know too.

For example and this is more anyone and not you because you know this
:-), who is getting insights from this discussion, lets say I start
typing:

dim [wcseRverapi] as new WCServerAPI

then on the next line I type:

WCSERVERAPI.WildcatServerConnectLocal(0) [Enter]

the editor will automatically change that to:

wcserRerapi.WildcatServerConnectLocal(0)

which is great because IntelliSense is HELPING the coder to understand
what is being used.

But to me, if I used a bracket, I would continue to refer to it for
readability from anywhere and not just the VS editor

[wcserverapi].WildcatServerConnectLocal(0)

Yes, its both the same here from the compiler standpoint, I see that,
but it is about code semantics and readability. Casing is VB/VB.NET is
irrelevant so things like this make sense.

Ironically, this is almost related to something I have to work out
very soon during my final cleanup of my new .NET suite of classes.

I drafted a post to get insights from people, but I still needed to
learn more. Basically, the organization of my assemblies, classes and
namespaces.

This all started with a 3rd party VB developer who took our VB6 .BAS
modules,

WCTYPES.BAS - Type structures, constants, etc
WCSERVER.BAS - declare imports for SDK functions)
WCVB.BAS - declare imports for helper WCVB.DLL for variants

and converted to .NET marshalling and merged it all into one module
namespace WCServerAPI in a file called WcServerAPI.VB. The file was
part of his project examples.

So using this module as a basis, I began my VB.NET venture and created
a project called wildcat.net.server, added the wcserverAPI.VB to the
project and changed the line:

Module WcServerAPI ==> public class WcServerAPI

compiled and viola.

Then I began to do the following which you can then see how some of my
forum post related to my tasks:

- see how to break it up, I immediately thought of "include"
(remember the include discussion? <g>) I see where Partial
Classes could help, but after exploring that, it might be
better to keep some things separate.

- Added Events to wrap the callbacks (remember that thread?)

- Added helper classes that wrap functionality

Basically overall, I started to explore and I am having a blast with
the VB.NET :-),

- what abstract classes I needed,
- Grasping memory management, disposal, can you trust GC?,
- Understanding "Self" or "this" ideas in classes (ME?),
- Where recursion is needed, and if this is good or bad in VB.NET
- where interfaces would apply for virtual I/O designs,
- where nested classes/structure can be used,
- where partial classes can be used,
- where Generic Classes and functions can help,
- how to leverage important ideas like
- operators
- properties
- default properties
- inherit type conversions (including XML)
- enumerators,
- etc.

One of the ways I learn is to RE-DO work I did in other languages. So
if already have something close to it in C/C++, rather than compile
it as C++/CLR (for now as I learn), I will seen how its done in VB.NET
or C#.

Here is a good example, in our native C/C++ WIN32 SDK, we have a group
of RPC client/server traversal functions:

BOOL GetFirstUser(DWORD keynum, TUser &u, DWORD &tid);
BOOL GetLastUser(DWORD keynum, TUser &u, DWORD &tid);
BOOL GetNextUser(DWORD keynum, TUser &u, DWORD &tid);
BOOL GetPrevUser(DWORD keynum, TUser &u, DWORD &tid);

where keynum can be one of these:

const int UserIdKey = 0;
const int UserNameKey = 1;
const int UserLastNameKey = 2;
const int UserSecurityKey = 3;
const int UserLastCallKey = 4;

where TUser is (shorten)

typedef struct tagTUserInfo {
DWORD Id;
char Name[SIZE_USER_NAME];
char Title[SIZE_USER_TITLE];
} TUserInfo;

typedef struct tagTUser {
DWORD Status;
TUserInfo Info;
...
} TUser;

I wanted to highlight TUserInfo "nested" structure because it promotes
recursion concepts in serialization, type automation needs.

Now, in our framework, we have three main databases:

Users
Files
Messages

So there similar traversal functions, for example for Files:

BOOL GetFirstFileRec(DWORD keynum, TFileRecord &f, DWORD &tid);
BOOL GetLastFileRec(DWORD keynum, TFileRecord &f, DWORD &tid);
BOOL GetNextFileRec(DWORD keynum, TFileRecord &f, DWORD &tid);
BOOL GetPrevFileRec(DWORD keynum, TFileRecord &f, DWORD &tid);

As you can see, the power of .NET generic functions, classes, types
can really make this REALLY sweet to generalize a .NET SDK framework.

So I just began to explore generic types and when I couldn't get it
compiled right, I explored and saw mixed usages of brackets like OF T
or Of [T] etc, hence the post. :-)

I think for the above, based on my knowledge thus far, it would be
begin with something like this (one way):

function GetFirst(Of T)(ByVal keynum as Uinteger, _
Of data as T, _
ByRef Tid as UInteger) as Boolean
function GetLast(Of T)(ByVal keynum as Uinteger, _
Of data as T, _
ByRef Tid as UInteger) as Boolean
function GetNext(Of T)(ByVal keynum as Uinteger, _
Of data as T, _
ByRef Tid as UInteger) as Boolean

function GetPrev(Of T)(ByVal keynum as Uinteger, _
Of data as T, _
ByRef Tid as UInteger) as Boolean

I think the implementation might be (for one)

function GetFirst(Of T)(ByVal keynum as Uinteger, _
Of data as T, _
ByRef Tid as UInteger) as Boolean

select case(TypeOf(Data))
case TUser : return GetFirstUser(keynum,data,tid)
case TFileRec : return GetFirstFileRec(keynum,data,tid)
end if
throw new Exception ("Unsupported type")
end function

Of course, a design with interfaces and delegates and emumerators is
probably be a very appropriate approach here, helping to remove parts
like typeof() select case.

So I'm learning the .NET semantics. :-)

--
 
Armin said:
It works because there is never a keyword after the dot.

BTW, what do you think is the name of the field? Is it "[String]" or is it
"String"? I've looked at the IL code and it says:

.field public string String

So, the brackets are _only_ there for the compiler to be able to
distinguish between an identifier and a keyword in it's first, lexical,
compilation pass. The brackets don't belong to the identifier itself,
i.e. they are removed.

Correct. I appreciate taking it to a levels I can grasp. :-)

Thanks Armin for being patience in my venture to understand VB.NET
semantics.

You see, this is important for a person like myself coming from a
C/C++ world where hungarian notations and lower/upper case matters. It
is fundamental in the readability and undertanding of APIs and
libraries. So not to argue, I have to have a small nit with you that
I do think its about code readability and developer semantics.

For example, when one sees an traditional WIN32 API function such as

BOOL xyz(LPCSTR a, LPVOID b)

you know right away that is a constant (byval) long pointer to a null
terminated string and a long pointer to a untyped variable. Like
wise, a Hungarian prefix is well understood by veteran C people.

But in regard to VB.NET brackets, this is common practice in C/C++
(and I guess C# too), where case is very important as you know:

TYPE_NAME type_name

ie.

HANDLE handle;
PHANDLE phandle;

From a code readability, when you see usages of type_name (lower
case), in the developers' or code readers' mind, they instantly know
it a variable of type TYPE_NAME

So I do think its about code readability and semantics because one
side would say that is a bad idea and another would say its not.

But if case is not a factor, then it can viewed as poor. The debates
on this has long been argued so lets do ourselves a favor and not
repeat what is better but I do wish to know what is recommended for
VB.NET.

In VB.NET, as you note, it doesn't matter because the compiler knows,
and also Intellisense seems to know too.

For example and this is more anyone and not you because you know this
:-), who is getting insights from this discussion, lets say I start
typing:

dim [wcseRverapi] as new WCServerAPI

then on the next line I type:

WCSERVERAPI.WildcatServerConnectLocal(0) [Enter]

the editor will automatically change that to:

wcserRerapi.WildcatServerConnectLocal(0)

which is great because IntelliSense is HELPING the coder to understand
what is being used.

But to me, if I used a bracket, I would continue to refer to it for
readability from anywhere and not just the VS editor

[wcserverapi].WildcatServerConnectLocal(0)

Yes, its both the same here from the compiler standpoint, I see that,
but it is about code semantics and readability. Casing is VB/VB.NET is
irrelevant so things like this make sense.

Ironically, this is almost related to something I have to work out
very soon during my final cleanup of my new .NET suite of classes.

I drafted a post to get insights from people, but I still needed to
learn more. Basically, the organization of my assemblies, classes and
namespaces.

This all started with a 3rd party VB developer who took our VB6 .BAS
modules,

WCTYPES.BAS - Type structures, constants, etc
WCSERVER.BAS - declare imports for SDK functions)
WCVB.BAS - declare imports for helper WCVB.DLL for variants

and converted to .NET marshalling and merged it all into one module
namespace WCServerAPI in a file called WcServerAPI.VB. The file was
part of his project examples.

So using this module as a basis, I began my VB.NET venture and created
a project called wildcat.net.server, added the wcserverAPI.VB to the
project and changed the line:

Module WcServerAPI ==> public class WcServerAPI

compiled and viola.

Then I began to do the following which you can then see how some of my
forum post related to my tasks:

- see how to break it up, I immediately thought of "include"
(remember the include discussion? <g>) I see where Partial
Classes could help, but after exploring that, it might be
better to keep some things separate.

- Added Events to wrap the callbacks (remember that thread?)

- Added helper classes that wrap functionality

Basically overall, I started to explore and I am having a blast with
the VB.NET :-),

- what abstract classes I needed,
- Grasping memory management, disposal, can you trust GC?,
- Understanding "Self" or "this" ideas in classes (ME?),
- Where recursion is needed, and if this is good or bad in VB.NET
- where interfaces would apply for virtual I/O designs,
- where nested classes/structure can be used,
- where partial classes can be used,
- where Generic Classes and functions can help,
- how to leverage important ideas like
- operators
- properties
- default properties
- inherit type conversions (including XML)
- enumerators,
- etc.

One of the ways I learn is to RE-DO work I did in other languages. So
if already have something close to it in C/C++, rather than compile
it as C++/CLR (for now as I learn), I will seen how its done in VB.NET
or C#.

Here is a good example, in our native C/C++ WIN32 SDK, we have a group
of RPC client/server traversal functions:

BOOL GetFirstUser(DWORD keynum, TUser &u, DWORD &tid);
BOOL GetLastUser(DWORD keynum, TUser &u, DWORD &tid);
BOOL GetNextUser(DWORD keynum, TUser &u, DWORD &tid);
BOOL GetPrevUser(DWORD keynum, TUser &u, DWORD &tid);

where keynum can be one of these:

const int UserIdKey = 0;
const int UserNameKey = 1;
const int UserLastNameKey = 2;
const int UserSecurityKey = 3;
const int UserLastCallKey = 4;

where TUser is (shorten)

typedef struct tagTUserInfo {
DWORD Id;
char Name[SIZE_USER_NAME];
char Title[SIZE_USER_TITLE];
} TUserInfo;

typedef struct tagTUser {
DWORD Status;
TUserInfo Info;
...
} TUser;

I wanted to highlight TUserInfo "nested" structure because it promotes
recursion concepts in serialization, type automation needs.

Now, in our framework, we have three main databases:

Users
Files
Messages

So there similar traversal functions, for example for Files:

BOOL GetFirstFileRec(DWORD keynum, TFileRecord &f, DWORD &tid);
BOOL GetLastFileRec(DWORD keynum, TFileRecord &f, DWORD &tid);
BOOL GetNextFileRec(DWORD keynum, TFileRecord &f, DWORD &tid);
BOOL GetPrevFileRec(DWORD keynum, TFileRecord &f, DWORD &tid);

As you can see, the power of .NET generic functions, classes, types
can really make this REALLY sweet to generalize a .NET SDK framework.

So I just began to explore generic types and when I couldn't get it
compiled right, I explored and saw mixed usages of brackets like OF T
or Of [T] etc, hence the post. :-)

I think for the above, based on my knowledge thus far, it would be
begin with something like this (one way):

function GetFirst(Of T)(ByVal keynum as Uinteger, _
Of data as T, _
ByRef Tid as UInteger) as Boolean
function GetLast(Of T)(ByVal keynum as Uinteger, _
Of data as T, _
ByRef Tid as UInteger) as Boolean
function GetNext(Of T)(ByVal keynum as Uinteger, _
Of data as T, _
ByRef Tid as UInteger) as Boolean

function GetPrev(Of T)(ByVal keynum as Uinteger, _
Of data as T, _
ByRef Tid as UInteger) as Boolean

I think the implementation might be (for one)

function GetFirst(Of T)(ByVal keynum as Uinteger, _
Of data as T, _
ByRef Tid as UInteger) as Boolean

select case(TypeOf(Data))
case TUser : return GetFirstUser(keynum,data,tid)
case TFileRec : return GetFirstFileRec(keynum,data,tid)
end if
throw new Exception ("Unsupported type")
end function

Of course, a design with interfaces and delegates and emumerators is
probably be a very appropriate approach here, helping to remove parts
like typeof() select case.

So I'm learning the .NET semantics. :-)

--
 
Armin Zingler said:
The _only_ reason to use them is to use a keyword as an identifier, be it
a
class name or a variable name.

One exception to this rule: A type's name is the same as one of the
keywords of the intrinsic types of VB, the namespace containing the custom
type is imported (explicitly or implicitly), and you want to use the type
without qualifying it by its namespace:

\\\
Private Sub Test()
Dim s As [String] ' Binds to the custom 'String' class.
Dim t As String ' Binds to 'System.String'.
End Sub
....
Public Class [String]
Public Value As String
End Class
///
 
Armin Zingler said:
The _only_ reason to use them is to use a keyword as an identifier, be it
a
class name or a variable name.

One exception to this rule: A type's name is the same as one of the
keywords of the intrinsic types of VB, the namespace containing the custom
type is imported (explicitly or implicitly), and you want to use the type
without qualifying it by its namespace:

\\\
Private Sub Test()
Dim s As [String] ' Binds to the custom 'String' class.
Dim t As String ' Binds to 'System.String'.
End Sub
....
Public Class [String]
Public Value As String
End Class
///
 
Herfried said:
Armin Zingler said:
The _only_ reason to use them is to use a keyword as an identifier,
be it a
class name or a variable name.

One exception to this rule: A type's name is the same as one of the
keywords of the intrinsic types of VB, the namespace containing the
custom type is imported (explicitly or implicitly), and you want to
use the type without qualifying it by its namespace:

\\\
Private Sub Test()
Dim s As [String] ' Binds to the custom 'String' class.
Dim t As String ' Binds to 'System.String'.
End Sub
...
Public Class [String]
Public Value As String
End Class
///


True, but I don't see the exception to the rule. With the first declaration
you want to use the keyword as an identifier. This _is_ the rule that you
quoted.


Armin
 
Herfried said:
Armin Zingler said:
The _only_ reason to use them is to use a keyword as an identifier,
be it a
class name or a variable name.

One exception to this rule: A type's name is the same as one of the
keywords of the intrinsic types of VB, the namespace containing the
custom type is imported (explicitly or implicitly), and you want to
use the type without qualifying it by its namespace:

\\\
Private Sub Test()
Dim s As [String] ' Binds to the custom 'String' class.
Dim t As String ' Binds to 'System.String'.
End Sub
...
Public Class [String]
Public Value As String
End Class
///


True, but I don't see the exception to the rule. With the first declaration
you want to use the keyword as an identifier. This _is_ the rule that you
quoted.


Armin
 
Ok, this is all very simple to me now.

It all stems from the fact VB/VB.NET is not case sensitive language
when it cames to identifiers.

It is long standard practice in languages like C/C++ and I guess C# to
use semantics such as:

TYPE_NAME type_name
i.e.

HANDLE handle;
LPCSTR lpcstr;
TXYZ xyz;

Because you can't readily do this in VB, for inherit keywords or
keywords that might conflict with existing identifiers, the brackets,
including name spaces helps serve this purpose. Of course, the
compiler and intellisense can determine what is what, but for
readability this can help the human code reader.

Thanks for your input

--
Armin Zingler said:
The _only_ reason to use them is to use a keyword as an identifier, be
it a
class name or a variable name.

One exception to this rule: A type's name is the same as one of the
keywords of the intrinsic types of VB, the namespace containing the
custom type is imported (explicitly or implicitly), and you want to use
the type without qualifying it by its namespace:

\\\
Private Sub Test()
Dim s As [String] ' Binds to the custom 'String' class.
Dim t As String ' Binds to 'System.String'.
End Sub
...
Public Class [String]
Public Value As String
End Class
///
 
Back
Top