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

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

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

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

9496閲覧

【C#】【Unity】IF文によるvarの宣言について

happypudding

総合スコア30

C#

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

1クリップ

投稿2017/10/17 06:56

編集2017/10/17 07:01

お世話になります。
初歩的な質問で申し訳ありません。
自分でなんとか調べようと思ったのですが、どう調べればよいかわからずに質問させていただきました。

C#

1public bool bl; 2Text txt; 3Image img; 4void test(){ 5 if(bl){ 6 var a=txt; 7 }else{ 8 var a=img; 9 } 10 11 a.color=0; //aはスコープ外で初期化されているのでNG 12}

上記のようなTextクラスとImageクラスに共通なcolorプロパティが存在する場合、
bool blがTrueかFalseかによって分岐し、var aの型が決定するようなプログラムを書きたいのですが、うまく行きません。
下記のようにスコープを外に出して宣言したとしても、型が推測できず、初期化できないのでビルド不可となります。

C#

1 2public bool bl; 3Text txt; 4Image img; 5void test(){ 6 var a;//varの場合、必ず初期化しないとNG 7 if(bl){ 8 a=txt; 9 }else{ 10 a=img; 11 } 12 13 a.color=0; 14}

何かしら良い書き方があると思うのですが、調べ方がわからず・・・
aのTypeが2-3種類ならまだIF文でなんとかなるのですが、種類が増え、さらに共通処理の部分が長くなると、プログラム自体が長くなるのでIF分で一つずつは書きたくないです。
どなたかご存じの方はご教授願えないでしょうか。よろしくお願いします。

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

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

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

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

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

guest

回答2

0

残念ですが、質問者様が本当にやりたいことは、不可能だと思われます。
先にご回答いただいていたように、変数の宣言の時点で型が決定している必要があります。

以下はC#のvarに関するリファレンスです。
var (C# リファレンス)

これによると

暗黙的に型指定されたローカル変数では、型を自分で宣言した場合と同様に厳密に型指定されますが、コンパイラが型を決定します。

とあり、宣言時にコンパイラが型を決定する為に、右辺の型が決まっている必要があります。
受け取りようによっては、「宣言した後の行で型が決定してもいいじゃないか」とも取れますが、そこは書いてないだけ、と言うことで。

したがいましてご要望の、継承関係に無い型の変数を自在にvarで取りまわせる「いい感じ」のコードは、C# 3.0以降の現在の言語仕様だと不可能だと考えます。


追記
回答および意見としては前と変わっていないのですが、少し興味を覚えたこともあったので追記させていただきます。(単なるトピックです。実際のプログラミングとしてはまったく勧められないものですのでご注意を)

'var a' の宣言時に型が確定さえすればコンパイルエラーを回避できるということで、では、全てのクラスの基底のクラスSystem.Objectを使えばいいのではないかと思い、試しました。
お使いの環境がUnityでもあるし、System.Object 自体、使えるかどうか.NET のバージョンに依存するようなので参考程度ですが。(Visual Studio 2017 でビルドした.NET Framework 4.6.1 のコンソールアプリです)

本質的には前回答者であるozwk様と同じことになります。更に、この例では var a で取りまわすと最後は結局、型に注意しなければならないコードになってしまうので、可読性を損います。そう言った意味でもこのようなコードは勧められないことになります。

C#

1using System; 2 3namespace ConsoleApp1 4{ 5 class Program 6 { 7 Text txt = new Text(); 8 Image img = new Image(); 9 10 static void Main(string[] args) 11 { 12 var program = new Program(); 13 program.Test(true); 14 program.Test(false); 15 } 16 17 void Test(bool bl) 18 { 19 // あえて全ての基底のobject型で初期化 20 //var a = new object(); 21 var a = new System.Object(); 22 if (bl) 23 { 24 a = txt; 25 } 26 else 27 { 28 a = img; 29 } 30 31 string typeS = a.GetType().ToString(); 32 Console.WriteLine("Type: " + typeS); 33 if (a is Text) 34 { 35 Console.WriteLine("a が Textクラスの場合: " + ((Text)a).text); 36 } 37 else if (a is Image) 38 { 39 Console.WriteLine("a が Imageクラスの場合: " + ((Image)a).color); 40 } 41 } 42 } 43 44 class Text 45 { 46 public string text = "Textクラス内のtextフィールド"; 47 } 48 49 class Image 50 { 51 public int color = 123; 52 } 53} 54

このプログラムの実行結果は以下のようになりました。
イメージ説明
ちょっと面白いと思ったのが、a.GetType().ToString()で正しく、その時に入っているオブジェクトのクラス/型が出力されているということです。

投稿2017/10/24 06:30

編集2017/10/24 09:28
dodox86

総合スコア9183

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

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

happypudding

2017/10/24 08:30

ありがとうございます!この情報が知りたかったです!! 不可能なのですね(^^)それを聞いて安心致しました。 ベストアンサーにしたいのですが、ベストアンサーをクリックミスしてしまいまして(泣) ベストアンサーは変更することができないのですね・・・高評価とさせていただきましたm(_ _)m
happypudding

2017/10/24 09:30

非情に興味深い実験をありがとうございます!! 一度こちらでもやってみます(^^)
dodox86

2017/10/24 09:31

コメントありがとうございます。回答にも書いてますが本質的には前回答者様と同じ意見ですので気になさらないでください。意見は変わっていませんが一部、興味を覚えたことがあったので確認して追記しました。よろしければ併せてご覧ください。
dodox86

2017/10/24 09:32

コメントがすれ違いました。読んでいただけてうれしいです。ありがとうございます。
guest

0

ベストアンサー

csharp

1Text txt; 2Image img; 3void test(){ 4 Graphic a; // TextもImageもGraphic 5 if(bl){ 6 a=txt; 7 }else{ 8 a=img; 9 } 10 a.color=0; 11}

投稿2017/10/17 07:13

編集2017/10/17 07:14
ozwk

総合スコア13528

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

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

happypudding

2017/10/17 11:04

ありがとうございます。 string型にはcolorプロパティはありませんが、例えばaにstring型も入る可能性もあるとしたらいかがでしょうか?
ozwk

2017/10/24 08:06

aがstringである可能性があるなら そもそもa.colorなんてコード書かないので そんな状況は考えません。
happypudding

2017/10/24 08:28

たしかにそうですね。ありがとうございました!
ozwk

2017/10/24 23:30

書くとしたらObject型で受けてGraphic型にキャストできたら colorを書き換えるみたいな感じになるんでしょうね
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問