質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

4回答

15436閲覧

子クラスでの静的メソッドの実装を保証したい

NullRe

総合スコア7

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2018/08/02 15:31

前提・実現したいこと

子クラスでの静的メソッドの実装を保証したいです。
インターフェース・抽象メソッド・仮想メソッド共にstaticは出来ないので悩んでいます。
出来なくなっている(≒しない方が良い)理由も可能であれば知りたいです。

該当のソースコード

c#

1public abstract class Something 2{ 3 //これらの処理は子クラスにより変えたい 4 //(abstract staticは出来ない) 5 public abstract static void Load(); 6 public abstract static void Save(); 7 8 //子クラスで共通の処理は親クラスに置きたい 9 public static void Hoge() 10 { 11 () 12 } 13} 14 15public class ChildSomethingA : Something 16{ 17 public override static void Load() 18 { 19 () 20 } 21 public override static void Save() 22 { 23 () 24 } 25}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

出来なくなっている(≒しない方が良い)理由

について。理由というか困ることなのですがabstractなSomethingを継承するChildSomethingBが別に存在したときにSomething.Load()が呼び出されたときABどちらのLoadを呼ぶべきか解決できないと思います。
また、継承させないという構文はないので、関数の呼び出しが解決できるかどうかが、実行時にしか判断できず、staticであるとか、静的型であるとかいった特性に矛盾する構造になっているように思います。

投稿2018/08/03 13:36

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NullRe

2018/08/03 14:01

回答ありがとうございます。 >ABどちらのLoadを呼ぶべきか解決できない 確かにそうですね…
guest

0

やりたいこと的には拡張メソッドでやる話かな。
いい感じに静的関数を呼び出す仕組みだし。
プライベートには、アクセスできないのが辛いけど。

インタフェース、拡張メソッドだと、この記事はいい。
https://www.buildinsider.net/column/iwanaga-nobuyuki/013
参考にならんかもしれないけど

あと、loadはともかく、saveは、静的関数でなくていいと思う。

俺だったら、インタフェースをつくって、共通部分を拡張メソッドにして、
それぞれのクラスで地道にload関数を作るかな。

投稿2018/08/02 16:36

編集2018/08/02 17:19
kiichi54321

総合スコア1984

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NullRe

2018/08/02 18:22 編集

回答ありがとうございます。 インターフェースと拡張メソッドだと、こういう感じでしょうか? //コメントだと<code>使えないんですね… public interface ISomething { string Load(); } public static class SomethingCommon { public static string Common(this ISomething i) { return "Common"; } } public class Something : ISomething { public string Load() { return "Load"; } } public class UseSomething { UseSomething() { var something = new Something(); Console.WriteLine(something.Common()); Console.WriteLine(something.Load()); } } ただ、これだと使用時にnewしないといけないので、若干違うような気がします。
kiichi54321

2018/08/02 19:07

Loadは、静的関数にすればいいし、 Loadの返り値は、自クラスのはずだから、どのみちnewするでしょ。
NullRe

2018/08/03 13:06 編集

上のコードだと、Loadはインターフェースがあるために静的メソッドに出来ませんでした。 またインターフェースの拡張メソッドは、Somethingから呼ぶ場合はインスタンス化する必要がある?ようでした。 確かにどのみちnewしたかもしれませんが、あくまで通常の静的メソッドと同じように呼べるかがやりたい事でした。 別記事も参考にした所、newせずに呼び出すことが出来ました。 ありがとうございます。
guest

0

C#11 からは インターフェスの静的仮想メンバーの対応が含まれているのでできますね!

https://learn.microsoft.com/ja-jp/dotnet/csharp/whats-new/tutorials/static-virtual-interface-members

投稿2023/06/16 01:32

juner

総合スコア95

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己解決

kiichi54321さんの回答とこちらの記事を参考に、それっぽい事は出来ました。

c#

1public interface ISomething 2{ 3 string Load(); 4} 5 6public class SomethingBase 7{ 8 protected SomethingBase() { } 9 public static string Common() 10 { 11 return "Common"; 12 } 13} 14 15public class Something : SomethingBase, ISomething 16{ 17 public static string Load() 18 { 19 return "Load"; 20 } 21 22 string ISomething.Load() 23 { 24 return Load(); 25 } 26} 27 28public class UseSomething 29{ 30 public UseSomething() 31 { 32 Console.WriteLine(Something.Common()); 33 Console.WriteLine(Something.Load()); 34 } 35}

投稿2018/08/03 12:42

編集2018/08/03 13:03
NullRe

総合スコア7

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問