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

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

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

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

Q&A

解決済

3回答

4751閲覧

オーバーライド時のvirtual、override記述について

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

0グッド

0クリップ

投稿2017/05/22 12:44

編集2017/05/22 12:50

###前提・実現したいこと
お世話になります。
現在、C#を勉強し始めたところ、コンパイラの動作と参考にしている教科書で食い違いがあった為、質問させていただきます。

【前提】C#における継承の学習中
教科書:
スーパークラスのオーバーライド元となるメソッドに「virtual」、
サブクラスのオーバーライド先となるメソッドに「override」を記述しなくとも、
コンパイル時にエラーが出るが、コンパイルはでき、実行もできる。

コンパイル時:
実際の警告文は下記参照願います。
警告文が発生し、EXEファイルが生成されない。

【実現したいこと】
以下のことを知りたいです。
初歩的なことで申し訳ありませんが、ご教授願います。

1.教科書の「警告は出るが、コンパイルできる」は正しいのか。
2.(1が正しいとして)どのようにすれば、コンパイルは通るのか。

###発生している問題・エラーメッセージ

inheritance.cs(53,35): warning CS0108: 'EnchancedMyObject.PrintData()' hides inherited member 'MyObject.PrintData()'. Use the new keyword if hiding was intended.

###該当のソースコード

C#

1 using System; 2 3 namespace foo 4 { 5 class Program 6 { 7 public static void Main(string[] args) 8 { 9 EnchancedMyObject obj = new EnchancedMyObject(); 10 obj.name = "テスト"; 11 obj.age = 20; 12 obj.mail = "sample@sample.com"; 13 obj.PrintData(); 14 obj.PrintDataEnchanced(); 15 Console.ReadKey(); 16 } 17 } 18 19 class MyObject 20 { 21 public string name = "(noname)"; 22 public int age = 0; 23 24 // オーバーライド元 25 public void PrintData() 26 { 27 Console.WriteLine("名前:{0}, 年齢:{1}歳", name, age); 28 } 29 } 30 31 class EnchancedMyObject : MyObject 32 { 33 public string mail = "(no mail)"; 34 35 // オーバーライド先 36 public void PrintData() 37 { 38 Console.WriteLine("Method\"PrintData\" was overrided."); 39 } 40 41 public void PrintDataEnchanced() 42 { 43 Console.WriteLine("名前:{0}" + Environment.NewLine + "年齢:{1}" + Environment.NewLine + "メール:{2}.", name, age, mail); 44 } 45 } 46 }

###試したこと
オーバーライドするメソッドにvirtual, overrideを記述している場合は問題なくコンパイルでき、実行してオーバーライドされていることを確認しています。

###補足情報(言語/FW/ツール等のバージョンなど)
現在、新しいものを試す意味も含め、OSXにVisual Studioをインストールし、
Visual Studio Codeにて、CSCを使用してコンパイルしています。
(実行時はMonoを使用)

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

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

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

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

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

guest

回答3

0

warning と書いてあるものは警告です。通常、警告が出ても実行ファイルは作られます。作られないとするなら、正しいコードで実行ファイルが作られるかどうか、またオプションが正しいかどうかを確かめてください。
警告を出さないようにするには、警告文の中で書かれている通り、new キーワードを使ってください。

投稿2017/05/22 12:57

Zuishin

総合スコア28660

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

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

退会済みユーザー

退会済みユーザー

2017/05/22 13:36

回答ありがとうございます。 オプションは盲点でした。しっかり確認してみます。 一応、現状ではvirtualとoverrideを記述することでコンパイルが通ることを確認しています。
guest

0

ベストアンサー

自己解決しました。
どうやら、教科書と自分の実行環境に違いがあった為、混乱したようです。

教科書:Visual Studio(バージョン不明)
自分:テキストエディタ(Visual Studio Code)

今回、問題となった部分は

C#

1// オーバーライド元 2public void PrintData() 3{ 4 Console.WriteLine("名前:{0}, 年齢:{1}歳", name, age); 5} 6 7// オーバーライド先 8public void PrintData() 9{ 10 Console.WriteLine("Method\"PrintData\" was overrided."); 11}

上記のコードで、

教科書:警告文は出るが、コンパイルが通り、実行できる。
自分:警告文が出て、コンパイルが通らない。

という部分でした。

どうやら、Visual Studioでは
上記のようなソースコード(virtual - override、newのどちらも無い)場合、
暗黙的にnewを追加し、コンパイル・実行しているようです。
(Visual Studio 2017で上記ソースコードを実行し、生成されたEXEファイルをデコンパイルしたら判明しました)
この機能の有無により、教科書と自分の実行結果が異なる結果となったようです。

また、CSCを使ったコンパイル時はご指摘があった通り、
/nowarnオプションを付与することで警告を無視したコンパイルができそうです。
(※申し訳ありませんが、時間の都合上、まだ未検証です)

###結論
結果の食い違いは実行環境の違いによるものでした。
Visual Studioでは設定にもよると思われますが、上記のソースコードは問題なく動作します。
IDEを使わず、自力でコンパイル・実行をする場合には、警告を無視するオプションが必要となるかと(未検証)。

投稿2017/05/22 23:43

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Zuishin

2017/05/22 23:52

nowarn は警告があってもコンパイルするオプションではなく、警告を出さないようにするオプションです。また CSC は警告があってもコンパイルします。そこではなく、VSCode の拡張機能のオプションを確認してください。
guest

0

1.教科書の「警告は出るが、コンパイルできる」は正しいのか。
2.(1が正しいとして)どのようにすれば、コンパイルは通るのか。

1.が正しくて、コンパイルできてるのですよね?そこは確認できているのでは?
コンパイルが通る=正しく動作する、ではないことは理解できていますよね?

コンパイルできたからと言って、それがプログラマの意図した挙動でないと予想されるので、コンパイラはわざわざ警告を出しているのでしょう。

親クラスと子クラスで「同じ名前のメソッド」が定義されていた場合、コンパイラはコードを書いた人が

  • ポリモーフィックな挙動を期待している
  • まったく無関係な別のメソッドとして親の挙動を隠蔽したい

のいずれかが判断できないので、前者の場合は virtual - override と付けてほしいし、後者の場合は new キーワードによってその意図を明確にして欲しいということです。自分が意図した内容に従いコードを書けばよいだけです。

投稿2017/05/22 12:59

koko_u

総合スコア936

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

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

退会済みユーザー

退会済みユーザー

2017/05/22 13:33

回答ありがとうございます。 >>1.が正しくて、コンパイルできてるのですよね?そこは確認できているのでは? >>コンパイルが通る=正しく動作する、ではないことは理解できていますよね? 自分の中では「コンパイル=ソースコードがマシン語に翻訳され、実行用ファイル(今回ならEXEファイル)が生成される」という認識になっています。 コンパイルがこの認識で合っているならば、現状はEXEファイルが出力されていないので、コンパイルは通っていないのかな、と思っています。 勉強用に作ったファイルなので、オプション関係も含め、もうちょっと弄り回してみます。
koko_u

2017/05/22 13:55

> 現状はEXEファイルが出力されていないので、コンパイルは通っていないのかな、と思っています。 質問文には「警告」しか記載されていないので、エラーを見逃しているのでなければ、プロジェクトの設定で「警告をエラーとして扱う」のオプションが設定されている可能性があります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問