Hi there,
i tried to write a construct where a “selector-method” returns a instance of a concrete class implementing an interface.
“SomeSelectorMethod” fails with “Type mismatch, cannot assign “SomeBaseClass” to “ISomeInterface”” in the example below.
If i cast the first item to the wanted Interface (like in “JustAnotherSelectorMethod”) it works.
namespace ConsoleApplication562;
type
ISomeInterface = public interface
method SomeMethod(someArg: Object);
end;
SomeBaseClass = public class
public
class method SomeSelectorMethod(a: Int32): ISomeInterface;
begin
// E62 Type mismatch, cannot assign "SomeBaseClass" to "ISomeInterface"
exit case a of
1: new Implementor1;
2: new Implementor2;
3: new Implementor3;
end;
end;
class method AnotherSelectorMethod(a: Int32): ISomeInterface;
begin
// It works, if two cases are commented out
exit case a of
1: new Implementor1;
//2: new Implementor2;
//3: new Implementor3;
end;
end;
class method JustAnotherSelectorMethod(a: Int32): ISomeInterface;
begin
// This works!
exit case a of
1: ISomeInterface(new Implementor1);
2: new Implementor2;
3: new Implementor3;
end;
end;
class method SomeOtherSelectorMethod(a: Int32): ISomeInterface;
begin
// This also works
if a = 1 then
exit new Implementor1;
if a = 2 then
exit new Implementor2;
if a = 3 then
exit new Implementor3;
end;
end;
Implementor1 = public class(SomeBaseClass, ISomeInterface)
public
method SomeMethod(someArg: Object); empty;
end;
Implementor2 = public class(SomeBaseClass, ISomeInterface)
public
method SomeMethod(someArg: Object); empty;
end;
Implementor3 = public class(SomeBaseClass, ISomeInterface)
public
method SomeMethod(someArg: Object); empty;
end;
Program = class
public
class method Main(args: array of String): Int32;
begin
readLn;
end;
end;
end.
Bonus observation
JustAnotherSelectorMethod translates to “wired” decompiled code…
public static ISomeInterface JustAnotherSelectorMethod(int a)
{
int num = a;
switch (num)
{
case 0:
return (ISomeInterface) null;
case 1:
return new Implementor1() as ISomeInterface;
case 2:
return (ISomeInterface) new Implementor2();
case 3:
return (ISomeInterface) new Implementor3();
default:
if (num != 1)
{
if (num != 2)
{
if (num != 3)
{
if (num != 0)
return (ISomeInterface) null;
goto case 0;
}
else
goto case 3;
}
else
goto case 2;
}
else
goto case 1;
}
}
…whereas funnily enough SomeOtherSelectorMethod results in exactly what i would expect using a case expression…
public static ISomeInterface SomeOtherSelectorMethod(int a)
{
switch (a)
{
case 1:
return (ISomeInterface) new Implementor1();
case 2:
return (ISomeInterface) new Implementor2();
case 3:
return (ISomeInterface) new Implementor3();
default:
ISomeInterface someInterface;
return someInterface;
}
}