Home > Blockchain >  C# generics issue that is not present in Java
C# generics issue that is not present in Java

Time:08-07

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.

CodePudding user response:

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]);
    }
}
  • Related