おそらく、大体こんな感じの実装になると思います。

```csharp
public static TResult CastByIsOp<TResult>(Control target)
    where TResult : Control
{
    if (target == null)
        // 例外を投げる？nullを返す？
    if (target is TResult)
        return (TResult)target;

    throw new Exception();
}

public static TResult CastByAsOp<TResult>(Control target)
    where TResult : Control
{
    if (target == null)
        // nullを返す？
    var result = target as TResult;
    if (result == null)
        throw new Exception();

    return result;
}
```

コメントで書きましたが、引数が`null`の場合にどうするかはいくつか選択肢があります。

* ArgumentNullExceptionを投げる
* キャスト失敗時と同じ例外を投げる
* `null`を返す

ただ、どれを選んだ場合でも「ガード節によるメソッド終了」となります。
ここで実装を見てみると、`is`演算子の場合は、

1. 異常系(引数が`null`)によるメソッド終了
1. 正常系によるメソッド終了
1. 異常系(キャスト失敗)によるメソッド終了

となります。
それに対して`as`演算子は、

1. 異常系(引数が`null`)によるメソッド終了
1. 異常系(キャスト失敗)によるメソッド終了
1. 正常系によるメソッド終了

となり、ガード節が並ぶため、より読みやすい実装となります。
もちろん、`!`演算子や`== false`とすることで同じ記述順は実現できますが、否定を使わなくても済むのであれば、わざわざ否定を用いて記述する意味はないでしょう。

さらに、引数が`null`の時にもしキャスト失敗時と同じ例外を投げていい場合、以下の記述で事足ります。

```csharp
public static TResult CastByAsOp<TResult>(Control target)
    where TResult : Control
{
    var result = target as TResult;
    if (result == null)
        throw new Exception();

    return result;
}
```

シンプルですね。
以上の理由により、`is`演算子を採用する意味は薄いと考えました。