継承した場合のstatic変数/関数の扱いについて悩んでいます
C#
1//Program.cs 2using System; 3using System.Collections.Generic; 4using System.Linq; 5 6namespace ConsoleApp1 7{ 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 var BoyDict = new Dictionary<string, int>() { { "Taro", 12 }, { "Jiro", 13 }, { "Sabu", 14 } }; 13 var GirlDict = new Dictionary<string, int>() { { "Ichi", 15 }, { "Ni", 16 }, { "San", 17 } }; 14 15 // DictionaryからBoyインスタンスを作成 16 var BoyList = BoyDict.Select(_boy => new Boy(_boy.Key, _boy.Value)).ToList(); 17 Console.WriteLine(String.Join(",", Boy.NameList)); // Taro,Jiro,Sabuが出るし、それで正しい 18 Console.WriteLine(String.Join(",", Girl.NameList)); // この時点はListが空であってほしいがTaro,Jiro,Sabuが出る 19 20 // DictionaryからGirlインスタンスを作成 21 var GirlList = GirlDict.Select(_girl => new Girl(_girl.Key, _girl.Value)).ToList(); 22 Console.WriteLine(String.Join(",", Boy.NameList)); // Taro,Jiro,Sabuが出てほしいがTaro,Jiro,Sabu,Ichi,Ni,Sanが出る 23 Console.WriteLine(String.Join(",", Girl.NameList)); // Ichi,Ni,Sanが出てほしいが、Taro,Jiro,Sabu,Ichi,Ni,Sanが出る 24 25 } 26 } 27}
C#
1// Person.cs 2using System; 3using System.Collections.Generic; 4using System.Text; 5 6namespace ConsoleApp1 7{ 8 abstract public class Person 9 { 10 string Name; 11 int Age; 12 public static List<string> NameList = new List<string>(); 13 14 public Person(string Name, int Age) 15 { 16 this.Name = Name; 17 this.Age = Age; 18 NameList.Add(Name); 19 } 20 21 public static void SaveNameList(){ 22 // NameListをcsvにする処理。これはBoy,Girlで共通 23 } 24 25 } 26 27 public class Boy : Person 28 { 29 30 public Boy(string Name, int Age) : base(Name, Age) 31 { 32 33 } 34 35 } 36 37 public class Girl : Person 38 { 39 40 public Girl(string Name, int Age) : base(Name, Age) 41 { 42 43 } 44 45 } 46 47 48}
このようにPersonクラスを継承したBoyクラスとGirlクラスがあります.
Personクラスはインスタンス生成時に自身の場のNameListに生成された人の名前のリストを自動的に保存します.
こんな感じで,BoyとGirlでそれぞれNameListを持たせたいのですが,実際にこのコードを実行すると,2つ問題があります.
1:Person Boy GirlのNameListが同一のものになっているので別々に持たせたいです.
Boy Girl側でPublic new static List<string> NameListをしたら持たせられるのですが,Person側でできないでしょうか?
2:staticメソッドのSaveNameListもPersonクラスのNameListを参照するため,想定の動作をしません.
どのようにすればよいでしょうか?
また,そもそも設計思想が間違っているのでしょうか?
(NameListをPersonのstaticにすべきでないなど)
2021/2/2追記:
みなさまから多くの意見を頂き本当にありがとうございます.
まず最初に謝らせていただくこととして,このコード例は問題を具体化したかったために,作った
ものです.
やりたかったことはabstract classを継承した子クラスが,それぞれstaticな変数を持つ時に親クラスでstatic宣言した場合,親クラスのものと同一のものになるのではなく,子クラスでstaticなものを持っていてほしいということです.(Personの場,Boyの場,Girlの場があり,それぞれに同様の意味を持つstaticな変数を持たせたい)
そして,staticな関数の中で,自身の場を参照したいような時にも親クラスの場を参照してしまうという問題点を解決したいというものです.
適当な例としてstaticなNameListと,staticなNameListをCSV出力する関数を挙げたつもりでしたが不適切でした.確かにPersonがNameListを持つべきではありません
例えば染色体(Chromosomes)をPersonは持っています.これはどのPersonにもあり,インスタンスごとに違うものでもないのでstaticです(もしかしてここの理解が間違っているのでしょうか?).ただし,Personの染色体はこの時点では不定なので,定義だけされています.
Personを継承したBoyも染色体を持ちます.Boyの場合はxyです.Girlの場合xxです.
この時Boy.Chromosomos="xy", Girl.Chromosomos="xx"だと思うので,親と,それを継承した子1, 子2......で別のstaticな変数が欲しいという場面はあると思います
またややこしい例を持ち出して申し訳ありませんが,私がNameListを例として挙げてしまったがために本筋と外れた議論になってしまったので追記させていただきます.
//追記その2
staticにすべき変数論に発散してしまったので,一度締めさせていただきます。
みなさまのご意見非常に勉強になりました.
頂いた意見の中では
- 抽象プロパティで定義する(もしかすると実際にはできない?)
- PersonMangerクラスで管理する
が特に参考になりました。
今回の例では具体的過ぎて,「Personであったらそのように実装すべきでない」という意見を数多く頂きましたが,実際クラスで一括管理したいstaticなものがあると思うのですが,どうやらstaticの認識がみなさまのものと違っているようです.もういちど勉強します・
回答5件
あなたの回答
tips
プレビュー