読者です 読者をやめる 読者になる 読者になる

自動プロパティに個別にアクセス修飾子を付ける

C#

自動プロパティに個別にアクセス修飾子を付けることができたことに、今日初めて気付いた。

これができると何が嬉しいかというと、例えばこんなプログラム・・・

public interface IOutputData
{
    // Outputは外部からsetして欲しくないので
    // このインターフェイスでgetのみ提供する
    public int Output { get; }
}

internal sealed class OutputData : IOutputData
{
    // IOutputDataが要求するのはgetのみだが、
    // 外部からは使用できないので、自動プロパティで楽をする
    public int Output { get; set; }
}

public sealed class InputData
{
    // 外部からgetする意味はないが、
    // 楽をするために自動プロパティで済ませる
    public int Input { get; set; }
    
    // OutputDataではなく、IOutputDataを返す
    public IOutputData Proc()
    {
        return new OutputData() { Output = Input * 2 };
    }
}
// 呼出し側
var input = new InputData()
{
    Input = 10
};
var output = input.Proc().Output;

・・・楽をするとか言う割には、コード量が多い。
これが、こうなる。

public sealed class OutputData
{
    // setをinternalにすることで、
    // 外部から使用できなくなった。
    // それに伴い、インターフェイスを削除
    public int Output { get; internal set; }
}

public sealed class InputData
{
    // getをprivateにすることで、setしかできないように。
    // オブジェクトイニシャライザ専用のプロパティという意図を表せている・・・
    // 気がする!
    public int Input { private get; set; }
    
    public OutputData Proc()
    {
        return new OutputData() { Output = Input * 2 };
    }
}

呼出し側は何も変更する必要がない。var 様々!


ちなみに自動プロパティを使わない場合はですね・・・

public sealed class OutputData
{
    int output;
    public int Output
    {
        get { return output; }
        internal set { output = value; }
    }
}

public sealed class InputData
{
    int input;
    public int Input { set { input = value; } }
    
    public OutputData Proc()
    {
        return new OutputData() { Output = Input * 2 };
    }
}

最初の実装がいかにアレか分かりますね・・・!