Is it fine to typecast from one implementation type to another while using an object?
Composition over inheritance and Strategy Pattern

I would, instead of having differents weapons implementing differents interfaces defining their behaviour, create classes that holds the logic of the behaviour

Let's consider a weapon can have a primary attack, a secondary one and reload.

The class could be defined as such :

abstract class Weapon
{
    public IWeaponPrimaryAttack WeaponPrimaryAttack { get; set; }
    public IWeaponSecondaryAttack WeaponSecondaryAttack { get; set; }
    public IReloadable Reloadable { get; set; }
}


Now, we can define classes that holds differents behaviours of the interfaces.

In example :

public class SlashAttack : IWeaponPrimaryAttack
{
    public void DoAttack()
    {
        Console.WriteLine("Performing a slash attack");
    }
}

public class StabAttack : IWeaponSecondaryAttack
{
    public void DoSecondaryAttack()
    {
        Console.WriteLine("Performing a stab attack");
    }
}

public class Shooting12Caliber : IWeaponPrimaryAttack
{
    public void DoAttack()
    {
        Console.WriteLine("Bam !");
    }
}

public class Caliber12Reloader : IReloadable
{
    public void Reload()
    {
        Console.WriteLine("Reloading caliber 12 !");
    }
}

public class ShootingWith556 : IWeaponPrimaryAttack
{
    public void DoAttack()
    {
        Console.WriteLine("Bam (version 5.56) !");
    }
}

public class Caliber556Reloader : IReloadable
{
    public void Reload()
    {
        Console.WriteLine("Reloading caliber 5.56 !");
    }
}


And now, you can use theses class as properties in differents weapon classes.

You'll implement once the methods and can use the same for differents weapons : 

public class Katana : Weapon
{
    public Katana()
    {
         WeaponPrimaryAttack = new SlashAttack();
         WeaponSecondaryAttack = new StabAttack();
    }
}

public class Machete : Weapon
{
    public Machete()
    {
         WeaponPrimaryAttack = new SlashAttack();
    }
}

public class Shotgun : Weapon
{
    public Shotgun()
    {
         WeaponPrimaryAttack = new Shooting12Caliber();
         Reloadable = new Caliber12Reloader();
    }
}

public class AssaultRifleWithBayonet : Weapon
{
    public AssaultRifleWithBayonet()
    {
         WeaponPrimaryAttack = new ShootingWith556();
         WeaponSecondaryAttack = new StabAttack();
         Reloadable = new Caliber556Reloader();
    }
}


Now, your methods implementations are refactored within classes and are reusable. You don't need to typecast to check if this or that interface is implemented.

if (weapon.Reloadable != null)
{
    weapon.Reloadable.Reload();
}
else
{
    Console.WriteLine("This weapon isn't meant to be reloaded");
}

/*
This works too if you want to omit the Reloadable != null

public class CannotReload : IReloadable
{
    public void Reload()
    {
        Console.WriteLine("This weapon isn't meant to be reloaded");
    }
}
*/