ジェネリッククラスの継承がうまくできない


ジェネリッククラスの継承が思うようにいきません。  
一応、実装自体はできているのですが、コードを簡略化する方法を探しています。  
検索しようにも、自分がやりたい方法を言語化できなかったため、こちらで質問させていただくことにしました。

### 準備

[code]

    class Weapon { }
    class Bomb : Weapon { }
    
    class MachineBase<T> where T : Weapon { }
    class Machine : MachineBase<Bomb> { }
    
[/code]

このコードを、以下のように継承します。

### ①現状のコード

[code]

    class RobotBase<T1, T2> where T1 : MachineBase<T2> where T2 : Weapon { }
    class Robot : RobotBase<Machine, Bomb> { }
    
[/code]

実装自体はできていますが、クラスを継承するたびに `<T1, T2>` と型を2つ指定する手間がかかります。  
Machineクラスが、`ジェネリック型にWeaponクラスを指定していることは明確`です。  
そのため、型指定を1つで済ませる方法があるのではないかと思い、以下のように改変しました。

### ②改変したコード（エラー）

[code]

    class RobotBase<T> where T : MachineBase<Weapon> { }
    class Robot : RobotBase<Machine> { }    //エラー
    
[/code]

型引数を1つに減らしました。  
RobotBase<T>クラスには何かしらの型を指定する必要があるため、`型制約そのものであるWeaponをジェネリック型に指定しています。`  
すると、後述のエラーが出るようになりました。

### エラーメッセージ

[code]

    "エラー    CS0311  型 'Machine' はジェネリック型またはメソッド 'RobotBase<T>' 内で型パラメーター 'T' として使用できません。'Machine' から 'MachineBase<Weapon>' への暗黙的な参照変換がありません。    "
    
[/code]

`Machine`は`MachineBase<Bomb>`を継承し、`Bomb`は`Weapon`を継承しているため、RobotBaseの<T>が、  
T = Machine = MachineBase<Bomb> = MachineBase<Weapon>  
と解釈されるのかと思ったのですが、エラーとなってしまいます。

[code]

    class Robot : RobotBase<Machine> { }    //エラー
    
[/code]

エラーの原因である上記の文を、

[code]

    class Robot : RobotBase<MachineBase<Weapon>> { }
    
[/code]

と書き換えると、エラーは消えました。

[code]

    class Robot : RobotBase<MachineBase<Bomb>> { }    //エラー
    
[/code]

と書き換えると、再びエラーが出ます。

恐らく、RobotBase<T>を実装する際、`Weaponを型指定したことがエラーの原因`だと思います。  
エラーを回避するために、型引数の指定を派生クラスに丸投げしようとすると、①のコードのように、型引数の指定が2個になってしまいます。  
引数の実装を派生クラスに任せつつ、引数の数は増やさない記法はあるのでしょうか。

### 質問したいこと

①のような継承をする場合に、型引数を1つで済ませる方法、  
または、②でエラーを出さないようにする実装方法が知りたいです。  
どちらも不可能であれば、本文のコードを根本から改変することになっても構わないので、引数の指定をできるだけ抑えた継承の方法を教えていただきたいです。




クラス名からの判断なので確実ではないですが、そもそもこの例では継承で解決するべきではないように見えます。  
WeaponとBombはis-
aの関係、MachineBaseとMachine、RobotBaseとRobotは抽象クラスとその具象化クラスということで、継承であっても問題なさそうです。  
しかしMachineBaseとWeapon、RobotBaseとMachineBaseはhas-
aの関係に見えるので、例えばコンストラクタで渡してメンバ変数に保持した方が良いのではないでしょうか。

もし本当にすべて継承で解決しなければならない理由があるのであれば、その理由を追記していただけるとよりよい回答が得られるかもしれません。

参考：[is-a](https://ja.wikipedia.org/wiki/Is-a)、[has-a](https://ja.wikipedia.org/wiki/Has-a)

