473,387 Members | 1,517 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Implementing "Is" C# in C++, msdn article

Hi all,

i've read this article
http://msdn2.microsoft.com/en-us/library/85af44e9.aspx who first
interest me much.
I've translated it to use generic instead of template :

generic < typename T, typename U >
Boolean isinst(U u)
{
return safe_cast< T >(u) != nullptr;
}

but i realised that this can't be really a good solution. For example,
this example :

Collections::ArrayList^ a = gcnew Collections::ArrayList();
if ( isinst< Collections::ICollection ^ >(a) )
Console::WriteLine("a is a ICollection ");

We can understand that the safe_cast is working, so the function
returns true.

Before reading this article, I used to compare object with such a way :

if (a->GetType() == Collections::ICollection::typeid)
Console::WriteLine("a is a ICollection ");

In this example, the if statement is false, because a is not a
ICollection.

Can you explain me where i am wrong ? Or is the Msdn article incomplete
?

Thanks in advance for your answers,

Nico

May 12 '06 #1
17 2274
<ni*************@motorola.com> wrote in message
news:11*********************@i39g2000cwa.googlegro ups.com...
Hi all,

i've read this article
http://msdn2.microsoft.com/en-us/library/85af44e9.aspx who first
interest me much.
I've translated it to use generic instead of template :

generic < typename T, typename U >
Boolean isinst(U u)
{
return safe_cast< T >(u) != nullptr;
}

but i realised that this can't be really a good solution. For example,
this example :

Collections::ArrayList^ a = gcnew Collections::ArrayList();
if ( isinst< Collections::ICollection ^ >(a) )
Console::WriteLine("a is a ICollection ");
This is testing for assignment compatibility - a Collections::ArrayList
instance can be assigned to a variable of type ICollection.

We can understand that the safe_cast is working, so the function
returns true.

Before reading this article, I used to compare object with such a way :

if (a->GetType() == Collections::ICollection::typeid)
Console::WriteLine("a is a ICollection ");

In this example, the if statement is false, because a is not a
ICollection.
This is testing for type identity - the type of a Collection::ArrayList is
exactly the type Collections::ArrayList and nothing else.

Can you explain me where i am wrong ? Or is the Msdn article incomplete
?


You're testing two different things, both are valid in some context.
Generally, assignment compatibility is what you're interested in. If you're
checking for type identity, you're probably not structuring your code
correctly, as tests for type identity (e.g. switch on type) can usually be
better handled by virtual functions.

-cd
May 12 '06 #2
>You're testing two different things, both are valid in some context.
Generally, assignment compatibility is what you're interested in. If you're
checking for type identity, you're probably not structuring your code
correctly, as tests for type identity (e.g. switch on type) can usually be
better handled by virtual functions.

Thanks for your answer,

I've never done c#, but i thought that the "Is" keyword was the same as
in VB.Net.

I thought to use this as in this example, to empty textbox control only
on my form :

for each (Control ^c in this->Controls)
if (c->GetType() == TextBox::typeid)
c->Text = "";

in VB, i probably had used the Is keyword to know if "c Is Textbox Then
...." ; but maybe in C# "Is" hasn't the same meaning.
Do you think here that I can avoid testing for type identity ?
Could you give me an example where testing for assignement can be
useful ? Usually, i know if I can cast something to something else ...
maybe in generics function ?

Best regards,

Nicolas H.

May 13 '06 #3
Your code for the equivalent of the C# "is" is correct.
i.e.,
if (a->GetType() == Collections::ICollection::typeid)
is equivalent to:
if (a is Collections::ICollection)

(regarding your follow-up post, "is" in C# is not the same as "Is" in VB).

The MSDN article, despite it's title, does not explain the C++/CLI
equivalent to the C# "is".
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C# to C++ converter & VB to C++ converter
Instant J#: VB to J# converter

"ni*************@motorola.com" wrote:
Hi all,

i've read this article
http://msdn2.microsoft.com/en-us/library/85af44e9.aspx who first
interest me much.
I've translated it to use generic instead of template :

generic < typename T, typename U >
Boolean isinst(U u)
{
return safe_cast< T >(u) != nullptr;
}

but i realised that this can't be really a good solution. For example,
this example :

Collections::ArrayList^ a = gcnew Collections::ArrayList();
if ( isinst< Collections::ICollection ^ >(a) )
Console::WriteLine("a is a ICollection ");

We can understand that the safe_cast is working, so the function
returns true.

Before reading this article, I used to compare object with such a way :

if (a->GetType() == Collections::ICollection::typeid)
Console::WriteLine("a is a ICollection ");

In this example, the if statement is false, because a is not a
ICollection.

Can you explain me where i am wrong ? Or is the Msdn article incomplete
?

Thanks in advance for your answers,

Nico

May 13 '06 #4
David Anton wrote:
Your code for the equivalent of the C# "is" is correct.
i.e.,
if (a->GetType() == Collections::ICollection::typeid)
is equivalent to:
if (a is Collections::ICollection)


No, it's not. C#'s 'is' is tests for assignment compatibility (or reference
convertability - same thing for this purpose).

In C++/CLI, dynamic_cast<T>(e) is equivalent to C#'s 'as' operator: e as T,
while safe_cast<T>(e) is equivalent to C#'s cast: (T)e.

The C# 'is' operator has no direct equivalent in C++/CLI, but is
functionally equivalent to dynamic_cast<T>(e) != nullptr, as illustrated in
the MSDN article mention in the original post of this thread.

Note that using constructs like

if (e is T)
{
T t = e as T;
// ...
}

is bad (but common) practice - and FxCop will warn you about it. Under the
covers, is and as are both doing a cast, so the above code needlessly
performs two identical casts in succession. In C# (or C++/CLI), it's more
efficient (and encouraged by FxCop and the .NET design guidelines) to write:

T t = e as T;
if (null != t)
{
// ...
}

or in C++/CLI

T t = dynamic_cast<T>(e);
if (t != nullptr)
{
// ...
}

-cd
May 13 '06 #5
ni*************@motorola.com wrote:
You're testing two different things, both are valid in some context.
Generally, assignment compatibility is what you're interested in.
If you're checking for type identity, you're probably not
structuring your code correctly, as tests for type identity (e.g.
switch on type) can usually be better handled by virtual functions.

Thanks for your answer,

I've never done c#, but i thought that the "Is" keyword was the same
as
in VB.Net.


The 'Is' operator in Vb.Net is somewhat different. In most cases, it's
syntactic sugar around a call to System::Obect::ReferenceEquals(e1, e2) -
except when it's used in an expression of the form If TypeOf e Is t, in
which case it's equivalent to C#'s 'is' operator.

I thought to use this as in this example, to empty textbox control
only
on my form :

for each (Control ^c in this->Controls)
if (c->GetType() == TextBox::typeid)
c->Text = "";

in VB, i probably had used the Is keyword to know if "c Is Textbox
Then ..." ; but maybe in C# "Is" hasn't the same meaning.
In C# you'd use 'is' in this case. In C++/CLI, you should use dynamic_cast.
Do you think here that I can avoid testing for type identity ?
It depends on what you intend to do. In this case, it looks like you're aim
is to clear the text from all text boxes, in which case type identity is
what you want.
Could you give me an example where testing for assignement can be
useful ? Usually, i know if I can cast something to something else ...
maybe in generics function ?


It's more likely to be useful in a generic function, but there are
non-generic cases as well.

For example, you might have a centrailzed Log() function that has special
support for logging collections, so inside such a hypothetical function you
might write:

void Log(object o)
{
if (o is ICollection)
{
// special ICollection logging
}
else
{
// non-ICollection logging
}
}

Here you're doing the functional equivalent of adding a virtual function to
System.Object, then overriding it in ICollection (neither of which is
actually possible, but you get the same effect).

Does that help?

-cd
May 13 '06 #6
ok, thanks for your help ...
in fact i was totaly lost with the As operator (i didn't know)

And i made a mistake with the dynamic_cast (and the safe_cast)

Then,
I've this method, coming from the Msdn article

template < class T, class U >
Boolean isinst(U u) {
return dynamic_cast< T >(u) != nullptr;
}

and this generic one i've made

generic <typename T, typename U>
bool is(U u)
{
return T::typeid == u->GetType();
}

This both method seems to do the same things (correct me if i'm wrong).
Should i prefer the dynamic_cast one, or the one that uses reflexion ?

Thanks for your answer,

Greats,

Nico

May 13 '06 #7
The following test whether 'a' is of type Collections::ICollection in C#:
if (a is Collections::ICollection)

The following tests whether 'a' is of type Collections::ICollection in
C++/CLI:
if (a->GetType() == Collections::ICollection::typeid)

There may be other ways of doing this in C++, but the above method is valid.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C# to C++ converter & VB to C++ converter
Instant J#: VB to J# converter

"Carl Daniel [VC++ MVP]" wrote:
David Anton wrote:
Your code for the equivalent of the C# "is" is correct.
i.e.,
if (a->GetType() == Collections::ICollection::typeid)
is equivalent to:
if (a is Collections::ICollection)


No, it's not. C#'s 'is' is tests for assignment compatibility (or reference
convertability - same thing for this purpose).

In C++/CLI, dynamic_cast<T>(e) is equivalent to C#'s 'as' operator: e as T,
while safe_cast<T>(e) is equivalent to C#'s cast: (T)e.

The C# 'is' operator has no direct equivalent in C++/CLI, but is
functionally equivalent to dynamic_cast<T>(e) != nullptr, as illustrated in
the MSDN article mention in the original post of this thread.

Note that using constructs like

if (e is T)
{
T t = e as T;
// ...
}

is bad (but common) practice - and FxCop will warn you about it. Under the
covers, is and as are both doing a cast, so the above code needlessly
performs two identical casts in succession. In C# (or C++/CLI), it's more
efficient (and encouraged by FxCop and the .NET design guidelines) to write:

T t = e as T;
if (null != t)
{
// ...
}

or in C++/CLI

T t = dynamic_cast<T>(e);
if (t != nullptr)
{
// ...
}

-cd

May 13 '06 #8
>In C# you'd use 'is' in this case. In C++/CLI, you should use dynamic_cast

you're answered while i was typing ...

Why prefering dynamic_cast ? to be more efficient ? Reflexion is a bad
idea ?
Greats,

Nicolas H

May 13 '06 #9
David Anton wrote:
The following test whether 'a' is of type Collections::ICollection in
C#:
if (a is Collections::ICollection)
No, it does not. This tests whether the type of a is assignment compatible
with Collections::ICollection.

The following tests whether 'a' is of type Collections::ICollection in
C++/CLI:
if (a->GetType() == Collections::ICollection::typeid)
This checks for type identify, as I said in the earlier post. The 'is'
keywork in C# does not test for type identity, but for type convertibility.
There may be other ways of doing this in C++, but the above method is
valid. --


Valid yes, but not equivalent - and producing different results in more
cases than not.

The above C++/CLI code is equivalent to the following C# code:

if (a.GetType() == typeof(Collections.ICollection))

-cd
May 13 '06 #10
ni*************@motorola.com wrote:
In C# you'd use 'is' in this case. In C++/CLI, you should use
dynamic_cast


you're answered while i was typing ...

Why prefering dynamic_cast ? to be more efficient ? Reflexion is a bad
idea ?


C#'s is and C++/CLI's dynamic_cast are identical - they generate identical
IL code. ALL casts in IL are dynamic, based on type metadata.

-cd
May 13 '06 #11
Ah... of course.
You're right Carl.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C# to C++ converter & VB to C++ converter
Instant J#: VB to J# converter

"Carl Daniel [VC++ MVP]" wrote:
David Anton wrote:
The following test whether 'a' is of type Collections::ICollection in
C#:
if (a is Collections::ICollection)


No, it does not. This tests whether the type of a is assignment compatible
with Collections::ICollection.

The following tests whether 'a' is of type Collections::ICollection in
C++/CLI:
if (a->GetType() == Collections::ICollection::typeid)


This checks for type identify, as I said in the earlier post. The 'is'
keywork in C# does not test for type identity, but for type convertibility.
There may be other ways of doing this in C++, but the above method is
valid. --


Valid yes, but not equivalent - and producing different results in more
cases than not.

The above C++/CLI code is equivalent to the following C# code:

if (a.GetType() == typeof(Collections.ICollection))

-cd

May 13 '06 #12
I should just stop myself after sticking my foot in my mouth earlier, but
don't you mean that C# "as" and "dynamic_cast" are equivalent? (not "is" and
"dynamic_cast"...?)
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C# to C++ converter & VB to C++ converter
Instant J#: VB to J# converter

"Carl Daniel [VC++ MVP]" wrote:
ni*************@motorola.com wrote:
In C# you'd use 'is' in this case. In C++/CLI, you should use
dynamic_cast


you're answered while i was typing ...

Why prefering dynamic_cast ? to be more efficient ? Reflexion is a bad
idea ?


C#'s is and C++/CLI's dynamic_cast are identical - they generate identical
IL code. ALL casts in IL are dynamic, based on type metadata.

-cd

May 13 '06 #13

"Carl Daniel [VC++ MVP]" <cp*****************************@mvps.org.nospam >
wrote in message news:%2****************@TK2MSFTNGP04.phx.gbl...
| ni*************@motorola.com wrote:
| >> In C# you'd use 'is' in this case. In C++/CLI, you should use
| >> dynamic_cast
| >
| > you're answered while i was typing ...
| >
| > Why prefering dynamic_cast ? to be more efficient ? Reflexion is a bad
| > idea ?
|
| C#'s is and C++/CLI's dynamic_cast are identical - they generate identical
| IL code. ALL casts in IL are dynamic, based on type metadata.
|
| -cd
|
|

I'm sure you meant:

C#'s as and C++/CLI's dynamic_cast are identical ..

Willy.
May 13 '06 #14
"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:u%****************@TK2MSFTNGP02.phx.gbl...

I'm sure you meant:

C#'s as and C++/CLI's dynamic_cast are identical ..


Indeed, yes! I think I said it correctly somewhere else in the thread :)

-cd
May 13 '06 #15
>> I'm sure you meant:
C#'s as and C++/CLI's dynamic_cast are identical ..
Indeed, yes! I think I said it correctly somewhere else in the thread :)


I'm a bit confused ...

if I've well understood, could i write the "as" and the "is" operator
like this ?

template < class T, class U >
Boolean is(U u)
{
return dynamic_cast< T >(u) != nullptr;
}

template < class T, class U >
T as(U u)
{
return dynamic_cast< T >(u);
}

Nicolas

May 13 '06 #16
<ni*************@motorola.com> wrote in message
news:11*********************@i39g2000cwa.googlegro ups.com...
I'm sure you meant: C#'s as and C++/CLI's dynamic_cast are identical ..

Indeed, yes! I think I said it correctly somewhere else in the thread :)


I'm a bit confused ...

if I've well understood, could i write the "as" and the "is" operator
like this ?

template < class T, class U >
Boolean is(U u)
{
return dynamic_cast< T >(u) != nullptr;
}

template < class T, class U >
T as(U u)
{
return dynamic_cast< T >(u);
}


You're not confused :)

-cd
May 13 '06 #17
Thanks for your help Carl,

this is really much clearer now.

Thanks to other too, your help was usefull to me too.
Best regards,

Nicolas H.

May 13 '06 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: tcarvin | last post by:
The .NET studio help system seems to use these odd URLs to locate (html) help files to display. But on my system, I get "Server not found" web errors whenever I access Help. What do I have to do...
9
by: Brad Ford | last post by:
I see posts concerning the use of Whidbey, I am new to MSDN, and I would very much like to try it out. There is even a "hands on tutorial", but the requirement is that you have Whidbey installed...
15
by: Barry | last post by:
Hi group, Does anyone know why I get a W3 validator error (click the validation link at the bottom of the page) for http://www.polisource.com/consumer-protection.shtml saying "Line 227, column...
24
by: hjbortol | last post by:
Hi! Is the expression "a >= b" equivalent to "a - b >= 0" in C/C++? Is this equivalence an IEEE/ANSI rule? Or is this machine/compiler dependent? Any references are welcome! Thanks in...
37
by: jht5945 | last post by:
For example I wrote a function: function Func() { // do something } we can call it like: var obj = new Func(); // call it as a constructor or var result = Func(); // call it as...
2
by: Clemens Vasters | last post by:
"Is anybody from Microsoft reading this?" Well ... actually .... no .... welll ... maybe if you're really lucky. Let me explain ... My name is Clemens Vasters and I am a Program Manager on the...
94
by: Samuel R. Neff | last post by:
When is it appropriate to use "volatile" keyword? The docs simply state: " The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.