By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,956 Members | 1,457 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,956 IT Pros & Developers. It's quick & easy.

Covariant returns

P: n/a
When implementing .net interfaces in vc++.net, is there anyway to get around
the "error C2392: : covariant returns types are not supported in managed
types" error?
I know how to do this in c#. Is it possible in c++.net 2003? If so, please
show me how? Will it be possible in c++.net 2005(beta?)?
Nov 17 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Hasani,
When implementing .net interfaces in vc++.net, is there anyway to get around the "error C2392: : covariant returns types are not supported in managed
types" error?
I know how to do this in c#. Is it possible in c++.net 2003?
Unfortunately, no, not directly. What C# does is not actually covariant
return types... it does a trick by which it "renames" the actual method
implementing the interface/base class method, and creates a new one with the
same name, essentialy.
If so, please
show me how? Will it be possible in c++.net 2005(beta?)?


With the new C++/CLI syntax, yes.
Consider this example:

#using <mscorlib.dll>
using namespace System;
public interface class IA
{
public:
Object^ GetIt();
};

public ref class B : public IA
{
protected:

virtual Object^ GetItFromIA() = IA::GetIt
{
return "Some other thing";
}

public:
virtual String^ GetIt() new
{
return "This is the String";
}
};
int main()
{
IA^ obj = gcnew B();
Console::WriteLine(obj->GetIt());
Console::WriteLine(((B^)obj)->GetIt());
}

Note: This is built using the May preview... haven't gotten beta 1 yet ;)

--
Tomas Restrepo
to****@mvps.org
Nov 17 '05 #2

P: n/a
Tomas Restrepo (MVP) wrote:
the "error C2392: : covariant returns types are not supported in managed
types" error?
I know how to do this in c#. Is it possible in c++.net 2003?

Unfortunately, no, not directly. What C# does is not actually covariant
return types... it does a trick by which it "renames" the actual method
implementing the interface/base class method, and creates a new one with the
same name, essentialy.


could you please give me an example how to achive this in C#? I didn't
succeed :(

Stefan
Nov 17 '05 #3

P: n/a
c# example.

class MyObject : ICloneable
{

//by doing this, you're making the method private and in order to access
this method, the object must be (up)casted to the interface
//in question. In this case, an ICloneable.
//e.x.:
// MyObject obj = new MyObject();
//ICloneable clone = (ICloneable) obj;
//clone.Clone();
object ICloneable.Clone()
{
//do whatever u want. usually u call the Clone method that
returns a strong typed object as I'm doing now
return Clone();
}

public MyObject Clone()
{
return (MyObject) MemberwiseClone();
}
}
"Stefan Slapeta" <st************@slapeta.com> wrote in message
news:cc**********@paperboy.Austria.EU.net...
Tomas Restrepo (MVP) wrote:
the "error C2392: : covariant returns types are not supported in managed
types" error?
I know how to do this in c#. Is it possible in c++.net 2003?

Unfortunately, no, not directly. What C# does is not actually covariant
return types... it does a trick by which it "renames" the actual method
implementing the interface/base class method, and creates a new one with the same name, essentialy.


could you please give me an example how to achive this in C#? I didn't
succeed :(

Stefan

Nov 17 '05 #4

P: n/a
Well, this leads me to my next question.

How would u implement the following in c++

lets say in a c# I created

public interface IFoo
{
Int32 GetValue();
}

public interface IBar
{
String GetValue();
}

so here you have 2 interfaces with signatures that only differ by return
type. If I wanted to make a clas FooBar in c++ that implements/inherits both
interfaces, how would I go about doing this. Please provide a code example
as you did b4 but using synatax that will compile in c++.net 7.0/7.1 (no ^,
ref, etc).

"Tomas Restrepo (MVP)" <to****@mvps.org> wrote in message
news:u9****************@TK2MSFTNGP09.phx.gbl...
Hasani,
When implementing .net interfaces in vc++.net, is there anyway to get around
the "error C2392: : covariant returns types are not supported in managed
types" error?
I know how to do this in c#. Is it possible in c++.net 2003?


Unfortunately, no, not directly. What C# does is not actually covariant
return types... it does a trick by which it "renames" the actual method
implementing the interface/base class method, and creates a new one with

the same name, essentialy.
If so, please
show me how? Will it be possible in c++.net 2005(beta?)?


With the new C++/CLI syntax, yes.
Consider this example:

#using <mscorlib.dll>
using namespace System;
public interface class IA
{
public:
Object^ GetIt();
};

public ref class B : public IA
{
protected:

virtual Object^ GetItFromIA() = IA::GetIt
{
return "Some other thing";
}

public:
virtual String^ GetIt() new
{
return "This is the String";
}
};
int main()
{
IA^ obj = gcnew B();
Console::WriteLine(obj->GetIt());
Console::WriteLine(((B^)obj)->GetIt());
}

Note: This is built using the May preview... haven't gotten beta 1 yet ;)

--
Tomas Restrepo
to****@mvps.org

Nov 17 '05 #5

P: n/a
Hasani (remove nospam from address) wrote:
How would u implement the following in c++

[SNIP]

so here you have 2 interfaces with signatures that only differ by return
type. If I wanted to make a clas FooBar in c++ that implements/inherits
both interfaces, how would I go about doing this. Please provide a code
example as you did b4 but using synatax that will compile in c++.net
7.0/7.1 (no ^, ref, etc).


First, this is one place where the new syntax is superior to the old syntax.
You will have better reliability that the compiler can do the right thing in
the new syntax. I'll present both the old and new syntax for completeness.
Here is the new syntax:

using namespace System;

public interface class IFoo {
int GetValue();
};

public interface class IBar {
String^ GetValue();
};

public ref class R : IFoo, IBar {
public:
virtual int G1() = IFoo::GetValue;
virtual String^ G2() = IBar::GetValue;
};

int R::G1() { return 42; }
String^ R::G2() { return "Hello World!"; }

int main() {
R^ r = gcnew R;
IFoo^ f = r;
IBar^ b = r;

Console::WriteLine(f->GetValue());
Console::WriteLine(b->GetValue());
}

And here is the old syntax:

#using <mscorlib.dll>

using namespace System;

public __gc __interface IFoo {
int GetValue();
};

public __gc __interface IBar {
String* GetValue();
};

public __gc class R : public IFoo, public IBar {
public:
virtual int IFoo::GetValue();
virtual String* IBar::GetValue();
};

int R::IFoo::GetValue() { return 42; }
String* R::IBar::GetValue() { return S"Hello World!"; }

int main() {
R* r = new R;
IFoo* f = r;
IBar* b = r;

Console::WriteLine(f->GetValue());
Console::WriteLine(b->GetValue());
}

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
This posting is provided AS IS with no warranties, and confers no rights.
Nov 17 '05 #6

P: n/a
you've just added another subscriber to your blog!!

Thx Bray!

"Brandon Bray [MSFT]" <br******@online.microsoft.com> wrote in message
news:eo**************@TK2MSFTNGP10.phx.gbl...
Hasani (remove nospam from address) wrote:
How would u implement the following in c++

[SNIP]

so here you have 2 interfaces with signatures that only differ by return
type. If I wanted to make a clas FooBar in c++ that implements/inherits
both interfaces, how would I go about doing this. Please provide a code
example as you did b4 but using synatax that will compile in c++.net
7.0/7.1 (no ^, ref, etc).
First, this is one place where the new syntax is superior to the old

syntax. You will have better reliability that the compiler can do the right thing in the new syntax. I'll present both the old and new syntax for completeness.
Here is the new syntax:

using namespace System;

public interface class IFoo {
int GetValue();
};

public interface class IBar {
String^ GetValue();
};

public ref class R : IFoo, IBar {
public:
virtual int G1() = IFoo::GetValue;
virtual String^ G2() = IBar::GetValue;
};

int R::G1() { return 42; }
String^ R::G2() { return "Hello World!"; }

int main() {
R^ r = gcnew R;
IFoo^ f = r;
IBar^ b = r;

Console::WriteLine(f->GetValue());
Console::WriteLine(b->GetValue());
}

And here is the old syntax:

#using <mscorlib.dll>

using namespace System;

public __gc __interface IFoo {
int GetValue();
};

public __gc __interface IBar {
String* GetValue();
};

public __gc class R : public IFoo, public IBar {
public:
virtual int IFoo::GetValue();
virtual String* IBar::GetValue();
};

int R::IFoo::GetValue() { return 42; }
String* R::IBar::GetValue() { return S"Hello World!"; }

int main() {
R* r = new R;
IFoo* f = r;
IBar* b = r;

Console::WriteLine(f->GetValue());
Console::WriteLine(b->GetValue());
}

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
This posting is provided AS IS with no warranties, and confers no rights.

Nov 17 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.