

C#を勉強中です。  
クラスの中のメソッドには返り値の型を指定しないといけないという部分で躓いています。  
文字列型や、数値型は、stringやintを指定すればいいと直感的にわかるのですが、  
インスタンスを返すにはどうしたらよいのでしょうか。  
またvoidというのは返り値がないものという認識であっていますでしょうか。

[code]

    public class HogeClass {
    
      void Fuga () {
        return new Piyo();
      }
    
    }
    
[/code]


CC BY-SA 3.0
2016-01-08T02:41:08.883
20730
2016-01-08T03:32:59.900
9149
question
c#
C#でインスタンスを返すメソッドの作り方


`void`のかわりにインスタンスの型名(`Piyo`)を指定します。

[code]

    Piyo Fuga () {
        return new Piyo();
    }
    
[/code]


CC BY-SA 3.0
2016-01-08T02:48:20.823
20732
2016-01-08T02:48:20.823
5750
20730
answer


struct、class、interface、および enum で定義したものも型として指定できます。  
マイクロソフトの資料だと「カスタム型」というそうです。  
<https://msdn.microsoft.com/ja-jp/library/ms173104.aspx>

ですので メソッドの戻り値型に `Piyo` を返すメソッドを定義すればよいです。

[code]

    public class hoge {
      Piyo Fuga() {
        return new Piyo();
      }
    }
    
[/code]

void はご認識の通り 返り値がない事を意味します。  
戻り値の型が void の場合、return は処理の中止するだけで値は返しません。


CC BY-SA 3.0
2016-01-08T03:02:01.327
20733
2016-01-08T03:02:01.327
5008
20730
answer


> `void`というのは返り値がないものという認識であっていますでしょうか。

あっています。

> インスタンスを返すにはどうしたらよいのでしょうか。

戻り値の型にクラス名そのものを指定します。  
thisキーワードを使うことで、メソッドが呼び出されたインスタンス自身を返すことも可能です。

[code]

        //自分自身のインスタンスを返すメソッド例
        public Hoge GetInstance()
        {
            return this;
        }
    
[/code]

メソッドを呼び出すためにインスタンスが必要なので、この例では意味がないようにも見えますが、例えば`StringBuilder`クラスでは`Append`メソッドの戻り値でインスタンスを返すことにより、
_メソッドチェーン_ を実現しています。

[code]

    var sb = new System.Text.StringBuilder();
    Console.WriteLine(sb.Append("文を").Append("つなげて").Append("登録しますよ").ToString());
    
[/code]

特定のクラスで新しいインスタンスを呼び出したい場合には、`static`メソッドを使用してインスタンスのない状態から作成することもできます。  
インスタンス作成時の処理を隠蔽したり、インタフェースを使ってインスタンスを作成する時などに使えます。

[code]

        public static Hoge Create()
        {
            var hoge = new Hoge();
            hoge.Name = "このインスタンスは静的メソッドから作られました。";
            return hoge;
        }
    
[/code]

さらにインスタンス作成時の処理を隠蔽したり、継承したクラスによって振る舞いを変えたりするために、インスタンス生成用のクラスを作ったりします。  
これを _ファクトリパターン_ といいます。

それぞれのコーディング方法にはメリットやデメリットがありますので、使用に際してはご自身で詳細を調べていただきますようお願いします。

検証に使ったコード：

[code]

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var hoge = new Hoge
                {
                    Name = "このインスタンスは自前で初期化されました。",
                };
                Console.WriteLine(hoge.Name);
                var hoge2 = hoge.GetInstance();
                Console.WriteLine(hoge2.Name);
                var hoge3 = Hoge.Create();
                Console.WriteLine(hoge3.Name);
                var factory = new HogeFactory();
                var hoge4 = factory.Create();
                Console.WriteLine(hoge4.Name);
                var sb = new System.Text.StringBuilder();
                Console.WriteLine(sb.Append("文を").Append("つなげて").Append("登録しますよ").ToString());
                Console.Read();
            }
        }
    
        public class Hoge
        {
            public string Name { get; set; }
            public Hoge GetInstance()
            {
                //自分自身のインスタンスを返す
                return this;
            }
    
            public static Hoge Create()
            {
                var hoge = new Hoge();
                hoge.Name = "このインスタンスはスタティックメソッドから作られました。";
                return hoge;
            }
        }
    
        public class HogeFactory
        {
            public Hoge Create()
            {
                var hoge = new Hoge
                {
                    Name = "このインスタンスはファクトリパターンで作られました。"
                };
                return hoge;
            }
        }
    }
    
[/code]


CC BY-SA 3.0
2016-01-08T03:32:59.900
20734
2016-01-08T03:32:59.900
9820
20730
answer