C# interface について

タグの編集
投稿者 ケンケン  (社会人) 投稿日時 2022/11/2 10:14:08
namespace OOP2_1
{
   public interface IMember
    {
        float Rate { get; }
    }
    public sealed class SliverMem : IMember
    {
       public float Rate => 1.0f;
    }
}

        private void Exebtn_Click(object sender, EventArgs e)
        {

            var value = Convert.ToInt32(input.Text);
            // 宣言する。
            IMember member;

            if (Silverbtn.Checked)
            {
                member = new SliverMem();
            }

            Resultlabel.Text = (value * member.Rate).ToString() + "円";
        }

    ここで、IMember member; に宣言していますがそれはなぜですか?
         ↑の書き方が理解出来ません。
    何方かわかる方、宜しくお寝いたします。

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2022/11/2 10:53:34
そのコードだと文法エラーになりませんか?
Silverbtn.Checked が false だった時、変数 IMember の値が未定義状態になってしまう気が。

> ここで、IMember member; に宣言していますがそれはなぜですか?
御自身で書かれたコードというわけでは無いのでしょうか。

動作や文法については説明できますが、コードを書かれた「意図」や「理由」については
書いた本人に問い合わせた方が良いと思いますよ。第三者には想像しかできませんので。

動作的には、member 変数のデータ型は、
「SliverMem クラスのインスタンスを格納でき、Rate プロパティにアクセスできる型」であれば良いので
 dynamic member;
 IMember member;
 SliverMem member;
のいずれであっても通るはずです。

推測ですが、恐らくはこれ以外にも省略されたコード(あるいはこれから書き加えるコード)が
他にもあって、最終的にはポリモーフィズムな実装にする、という事では無いでしょうか?

つまり、member 変数に入るオブジェクトが SliverMem インスタンスだけではなく、
それ以外の型(IMember インターフェイスを任意の型)であることを期待している、という事です。


> var value = Convert.ToInt32(input.Text);
空文字列など、数値化できない文字列が入力されていた場合、これだとエラーになります。

文字列の中身が正しく変換できることを保証できている場合は Convert.ToInt32 でも構いませんが、
入力値を保証できない場合は、Convert.ToInt32 ではなく int.TryParse メソッドで変換することをお奨めしておきます。
// 修正案1
int.TryParse(input.Text, out int value); // 整数変換できない文字列の場合、value は 0 になる

// 修正案2
if (!int.TryParse(input.Text, out int value)) {
    // 整数変換できなかった場合の処理を記述
} else {
    // 整数変換できた場合の処理を記述 (value に整数が入っている)
}
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2022/11/2 10:59:21
> そのコードだと文法エラーになりませんか?
どちらかというと、コンパイルエラー、かな。

// 修正案1
IMember member = null;
if (Silverbtn.Checked)
{
    member = new SliverMem();
}
Resultlabel.Text = $"{value * member?.Rate}円";



// 修正案2
if (Silverbtn.Checked)
{
    IMember member = new SliverMem();
    Resultlabel.Text = (value * member.Rate) + "円";
}
投稿者 ケンケン  (社会人) 投稿日時 2022/11/2 10:59:49
このコードは、ネットのサンプルコードです。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2022/11/2 11:03:57
> このコードは、ネットのサンプルコードです。
であれば、せめて引用元を示すべきかと思いますよ。
投稿者 ケンケン  (社会人) 投稿日時 2022/11/2 15:06:25
色々ご指摘ありがとうございます。
回答の文面を読んで理解したいと思います。