Casting problem in .Net Compact Framework

Hi there,

I have a problem with a cast two objects in .Net Compact framework but the same problem doesn't occur in .net. I have an Interface InterfaceA that inherits an interface InterfaceB. Later I have a method that get Interface InterfaceB and returns Interface InterfaceB.
When I pass in an object of an implementation of the InterfaceA interface to InterfaceB, I guet the values passed in without problem. However when I cannot get the values returned from the methods because I get a casting error.

Can some one help with this?
public InterfaceB methodA (InterfaceB param)
{
//do some work
return param;
}

InterfaceA object1 = (Interface)methodA(object1);

Open in new window

LVL 4
karakavAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

withCommented:
Hi karakav,

I think that because it is possible to create an object that is only InterfaceB (in other words, it is possible to create an object that implements only InterfaceB and not InterfaceA), this means that methodA must treat the return value as a "pure" InterfaceB.  It's not always guaranteed that what gets returned by methodA could necessarily be cast into an InterfaceA, because the object might not implement that interface anymore than it might implement InterfaceQ or InterfaceZ.

If your version of the compact framework supports it, this may be a good scenario for using generics.  This way you can pass in "anything, so long as it implements InterfaceB" and the return type will be whatever that "anything" is.

public T methodA<T>(InterfaceB param) where T : InterfaceB
{
	//do some work
	return (T)param;
}

InterfaceA object1 = methodA<InterfaceA>(object1);

Open in new window

0
withCommented:
Whoops, correction: you would also want "param" to be of type T in the method signature...
public T methodA<T>(T param) where T : InterfaceB
{
	//do some work
	return param;
}

InterfaceA object1 = methodA<InterfaceA>(object1);

Open in new window

0
karakavAuthor Commented:
Yeah, I understand I can use generic, but in my case it is some thing I have already used in .net and I wanted to know if there is a limitation in .net compact framework.
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

alexey_gusevCommented:
what's the error exactly, and what's cf.net version?

the following snippet compiles perfectly in cf.net 3.5, please correct it if it is not what you are doing.
using System;
using System.Collections.Generic;
using System.Text;

namespace interfaceCast
{
    class Program
    {
        static void Main(string[] args)
        {
            AA aa = new AA();
            A a = (A)foo(aa);
            test(aa);
        }

        static B foo(B param)
        {
            return param;
        }

        static void test(A a)
        {
            a = (A)foo(a);
        }
    }

    interface B
    {
        int if1();
    }

    interface A : B
    {
        bool if2();
    }

    class AA : A
    {
        public AA() { }

        public int if1() { return 0;  }
        public bool if2() { return false; }
    }
}

Open in new window

0
alexey_gusevCommented:
tried it in cf.net 2.0 too
0
fromerCommented:
public InterfaceA : InterfaceB
{
}

public static class SomeClass
{
  public static InterfaceB MethodA(InterfaceB parameter)
  {
    return parameter;
  }  
}

public ObjectA : InterfaceA
{
}

public ObjectB : InterfaceB
{
}

InterfaceA returnValue =  (InterfaceA)SomeClass.MethodA(new ObjectA());

you get no error here, because ObjectA implements InterfaceA...

InterfaceA returnValue = (InterfaceA)SomeClass.MethodA(new ObjectB());
you get error here, because ObjectB doesn't implement InterfaceA...

is that the case of you?

0
karakavAuthor Commented:
Hi guys,
Sorry for the late answer.

I changely changed the solution of alexey_gusev to reflect the problem I am having.
Please not that in the foo method, when you return an implementation of B (BB in this case), you get a runtime error.
    class Program
    {
        static void Main(string[] args)
        {
            A a = new AA();
            a = (A)foo(a);
            test(a);
        }

        static B foo(B param)
        {
            return new BB();
            //return param;
        }

        static void test(A a)
        {
            a = (A)foo(a);
        }
    }

    interface B
    {
        int if1();
    }

    interface A : B
    {
        bool if2();
    }

    class AA : BB, A
    {
        public bool if2() { return false; }
    }

    class BB : B
    {
        public int if1()
        {
            return 10;
        }
    }

Open in new window

0
alexey_gusevCommented:
huh? unless I'm missing something,

BB implements B
A is NOT a base class for B, but its derived interface

so it all ends up in the following:

- you created the instance of the class BB in foo()
- you're trying to cast it to A, which is nowhere in the inheritance tree for BB, ie there are no conversion operators defined
0
withCommented:
Try this in Compact .NET.  It's the same sample you posted, with more obvious names to help follow it through.

You should be able to get this to run by choosing the "return param" route of the MakeShorter (aka "foo") method.

In your original question, you were returning the param, not making a new class, right?  Which do you need to do?
class Program
{
	interface IHaveHeight
	{
		int height { get; set; }
	}

	interface IThink : IHaveHeight
	{
		bool isthinkingaboutpizza { get; set; }
	}

	class Mammal : IHaveHeight
	{
		public int height { get; set; }
		public Mammal()
		{
			height = 10;
		}
	}

	class Human : Mammal, IThink
	{
		public bool isthinkingaboutpizza { get; set; }
		public Human()
		{
			isthinkingaboutpizza = true;
		}
	}

	static void Main(string[] args)
	{
		IThink joe = new Human();
		joe = (IThink)MakeShorter(joe);
		ThinkingAboutPizzaMakesYouShorter(joe);
	}

	static IHaveHeight MakeShorter(IHaveHeight param)
	{
		param.height--;

		//If you do this, what gets returned is a new simple Mammal that cannot think. 
		//So it cannot be cast to Human or IThink
		return new Mammal(); 

		//If you do this, joe remains intact and can be cast to anything else
		return param; 
	}

	static void ThinkingAboutPizzaMakesYouShorter(IThink thinker)
	{
		if (thinker.isthinkingaboutpizza)
		{
			//Assignment is pointless here
			thinker = (IThink)MakeShorter(thinker); 

			//This would do this same thing:
			MakeShorter(thinker);
		}
	}
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
karakavAuthor Commented:
Thanks guys. And sorry for the delay.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.