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?
 
withConnect With a Mentor Commented:
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
 
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
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
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
 
alexey_gusevConnect With a Mentor Commented:
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
 
fromerConnect With a Mentor Commented:
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_gusevConnect With a Mentor Commented:
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
 
karakavAuthor Commented:
Thanks guys. And sorry for the delay.
0
All Courses

From novice to tech pro — start learning today.