Issue
I'm having some difficulties understanding how csharp's generics work compared to Java ones.
I have written the following example in both c# and java
java
abstract class Gun { }
class Laser extends Gun { }
class Flamethrower extends Gun { }
abstract class GunConfig<T extends Gun> {
public T gun;
}
class LaserConfig extends GunConfig<Laser> { }
class FlamethrowerConfig extends GunConfig<Flamethrower> { }
public class MyClass {
public static void main(String args[]) {
GunConfig[] configs = new GunConfig[2];
configs[0] = new FlamethrowerConfig();
configs[1] = new LaserConfig();
System.out.println(configs[0]);
System.out.println(configs[1]);
}
}
csharp
abstract class Gun { }
class Laser : Gun { }
class Flamethrower : Gun { }
abstract class GunConfig<T> where T : Gun {
public T gun;
}
class LaserConfig : GunConfig<Laser> { }
class FlamethrowerConfig : GunConfig<Flamethrower> { }
public class Program
{
public static void Main()
{
GunConfig<Gun>[] configs = new GunConfig<Gun>[2];
configs[0] = new FlamethrowerConfig(); // <--- Cannot implicitly convert 'FlamethrowerConfig' into 'GunConfig<Gun>'
configs[1] = new LaserConfig();
Console.WriteLine(configs[0]);
Console.WriteLine(configs[1]);
}
}
Before adding the generic type to the GunConfig class I had something like this
abstract class GunConfig {
public Gun gun;
}
class LaserConfig : GunConfig {
public void DoSomething() {
var laser = (Laser)gun;
}
}
I simply used to cast the base Gun instance to whatever my class was supposed to use, that make it so you can have a LaserConfig instance with another type of Gun based instance inside which would make the cast fail.
Solution
You can add another non-generic GunConfig
class and derive GunConfig<T>
from it - to circumvent that collection typeparameter issue. It's a little annoying with the extra class you don't really need outside the collection, but actually only one or two more lines of code.
abstract class Gun { }
class Laser : Gun { }
class Flamethrower : Gun { }
abstract class GunConfig { // this resolves the type mismatch issue
}
abstract class GunConfig<T> : GunConfig where T : Gun {
public T gun;
}
class LaserConfig : GunConfig<Laser> { }
class FlamethrowerConfig : GunConfig<Flamethrower> { }
public class Program
{
public static void Main()
{
GunConfig[] configs = new GunConfig[2];
configs[0] = new FlamethrowerConfig(); // no error now
configs[1] = new LaserConfig();
Console.WriteLine(configs[0]);
Console.WriteLine(configs[1]);
}
}
Answered By - lidqy
Answer Checked By - Gilberto Lyons (JavaFixing Admin)