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

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

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

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

Unity

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

Q&A

解決済

2回答

3603閲覧

unity C# position 読み取り専用

eggpol

総合スコア60

C#

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

Unity

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

0グッド

0クリップ

投稿2016/11/04 06:03

unityのtransform.positionについて

positionをaseembly browserでみたところ
下記のようになりました。
position.xは読み取り専用であるというのはわかります。しかし、下にはpositionのプロパティが描かれているだけでposition.xなどpositionのフィールの確認ができないので読み取り専用かどうか判断できません。

これはどういう仕組みなのでしょうか?

public Vector3 position {
get;
set;
}

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

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

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

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

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

guest

回答2

0

ベストアンサー

C#のvalue typeの言語仕様のためだと思います。
C#の型にはclass(参照型)とstruct(値型)の2種類があります。Vector3は値型なのですが、値型というのはメソッドからリターンしたり別の変数に代入したりすると実体そのものではなくて実体がコピーされたものが値となります。ややこしく聞こえるかもしれませんが・・・

C#

1public struct Vector3 { 2 public float x; 3 public float y; 4 public float z; 5 ... 6} 7 8public class MyClass { 9 public Vector3 property { get; set; } 10 public Vector3 field; 11} 12 13void MyMethod() { 14 MyClass m = new MyClass(); 15 Vector3 p; 16 17 p = m.field; // m.fieldの内容がコピーされそれがpに設定される 18 p.x = 1.0f; // p.x を変更しても m.field.x の値は変わらない 19 m.field.x = 1.0f; // 値型(Vector3)であってもそれがフィールドならば、値型のメンバーを直接変更できる 20 21 p = m.property; // m.propertyの内容がコピーされそれがpに設定される 22 p.x = 1.0f; // p.x を変更しても m.property.x の値は変わらない 23 p.property.x = 1.0f; // 値型(Vector3)のプロパティーはそのメンバーを直接変更できない。 24 25}

m.field.x = 1.0fという代入文をコンパイラーが解析する際に、コンパイラーはmがMyClassであり、MyClassのインスタンスの構造は次のようになっているというところまで解析し、「MyClassに定義されているVector3型のフィールドの中にあるxというフィールドを変更する」と解釈してくれます。

MyClassのインスタンス +------+ |field | | x | <=ここに1.0fを代入すると解釈してくれる。 | y | | z | |... |

一方同じVector3型でもプロパティーになっていると、m.property.x = 1.0fと書いた場合にコンパイラーは
m.getProperty().x = 1.0fと解釈します。getProperty()の戻り値はm.propertyの元の値のコピーなのでそのフィールドxを変更しても元のm.property.xの値は変わりません。
さて、プロパティーやフィールドは似た構文で代入や設定ができるため、プロパティーに対して

m.property.x = 1.0f

を許すとプログラマーにはm.property.xの値を変更したかのように見えてしまいます。そこでC#のコンパイラーはこういったうっかりミスを防ぐために親切でエラーにしてくれているものと思われます。

投稿2016/11/04 11:06

編集2016/11/04 11:54
KSwordOfHaste

総合スコア18392

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

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

eggpol

2016/11/04 14:47

わかりやすく丁寧な回答ありがとうございます まず、自動プロパティというのがC# 3.0 で追加されたことを知りませんでした・・・ つまり、プロパティ public Vector3 property { get; set; }を作った場合 private  Property が自動生成される。 Propertyに初期化される値はVector3構造体であるためVector3型でないと初期化されないということですね。 しかし、これだとプロパティのフィールドがある意味がないですね。だから親切でエラーにしてくれているということがわかりました・・・・・
guest

0

気になったので調べたらドンピシャな記事がありました。
Transform.positionの代入とCS1612エラーで色々考えた - kurihara-nの日記

つまりどういうこと?という個人的解釈が以下です。

■普通のVector3の場合
Vector3 vector.x = 1.0f; は
Vector3クラスの中に「public float x { get; set; }」というメソッド(みたいなもの。正式にはプロパティ)がある。それを利用しているから問題無い。

■Transform.positionの場合
Transformクラスには「public Vector3 position { get; set; }」というメソッド(プロパティ)がある。position(Vector3自体)を変更する場合はそれを利用しているから問題無い。
でも「public float position.x { get; set; }」というメソッド(プロパティ)は存在しない。
存在しないメソッドを呼び出すことは出来ないからエラーになる。

■見分けを付けるには?
リファレンスにも出ていないっぽいので、上記ブログのように拡張メソッドを用意するか、経験則で覚える・エラーが出たら直すしかないかと思います。

投稿2016/11/04 08:25

sakura_hana

総合スコア11425

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

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

KSwordOfHaste

2016/11/04 17:55

リファレンスはライブラリーの仕様についてのドキュメントです。本件はC#言語そのものの仕様に関するものなのでリファレンスではなくC#の言語仕様書に記載されている(はず)です。例えばVS2015をインストールするとC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC#\Specifications\1033\の下に言語仕様書が入ってます。どんな言語でもそうなのですが、非常に形式的に書かれており読みにくい一方、詳細かつ厳密にかかれているので「~ってどういう仕様なのだろう」といった疑問の答えが必ず書いてあります。
sakura_hana

2016/11/05 05:43

勉強になりました。お教え頂きありがとうございます。
eggpol

2016/11/13 11:03

返信遅くなってすいません、回答ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問