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

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

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

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

Unity

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

Q&A

解決済

3回答

1160閲覧

クラスをStackにまとめて、メソッド内でStackからクラスのフィールドにアクセスできない。

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity

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

0グッド

0クリップ

投稿2018/02/17 08:19

編集2018/02/17 11:55

前提・実現したいこと

指定したクラスをStackに入れました。
メソッド内でそのStackを受け取り、Stackの各要素のクラスのプロパティにアクセスしたいのですが、
エラーになります(下記コードのコメント部分です)。
メソッド内で、Stackの各要素のクラスのプロパティにアクセスすることが可能であれば、
下記コードの修正方法を教えていただきたいです。
また、不可能であった場合、下記コードの意図したいことに近い形のものを教えていただきたいです。

※やりたいことを質問用に簡素化したのがTestクラスです。
Stackの要素に直接stringを入れる仕様は考えていません。

C#

using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Linq; class Test{ string s =""; public Test(string b){ s = b; } } public class Sample : MonoBehaviour { void Start () { Stack<Test> tests = new Stack<Test>(); tests.Push (new Test ("1")); tests.Push (new Test ("2")); tests.Push (new Test ("3")); string content = getReverseTest<Test> (tests); Debug.Log (content); } string getReverseTest<T>(Stack<T> tests){ string content = ""; for (int i = 0; i < tests.Count; i++) { //.sにアクセスしたいけど、認識してくれない。 content += tests.ElementAt (tests.Count - i - 1).s; } return content; } }

###追記。
sをpublicにしてみましたが、エラーメッセージが表示されます。

class Test{ public string s =""; public Test(string b){ s = b; } }
Assets/Sample.cs(33,53): error CS1061: Type `T' does not contain a definition for `s' and no extension method `s' of type `T' could be found. Are you missing an assembly reference?

###追記②

using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Linq; class Test{ public string s =""; public Test(string b){ s = b; } } public class Sample : MonoBehaviour { void Start () { Stack<Test> tests = new Stack<Test>(); tests.Push (new Test ("1")); tests.Push (new Test ("2")); tests.Push (new Test ("3")); string content = getReverseTest<Test> (tests); Debug.Log (content); } string getReverseTest<Test>(Stack<Test> tests){ string content = ""; for (int i = 0; i < tests.Count; i++) { content += tests.ElementAt (tests.Count - i - 1).s; } return content; } }
error CS1061: Type `Test' does not contain a definition for `s' and no extension method `s' of type `Test' could be found. Are you missing an assembly reference?

ちなみに下記は通ります。

string ss = new Test ("1").s; Debug.Log (ss); //1

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

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

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

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

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

guest

回答3

0

こんにちは。

s がprivateだからです。publicにすればアクセスできる筈です。

public string s ="";

因みに、このsはフィールドです。プロパティではありません。


【質問の追記への回答】
見落としてました。getReverseTest<T>というジェネリクスだったのですね。
Tがメンバsを持っている旨指定しないとダメな筈ですが、そのような直接の指定はできません。
Tの条件はwhere節で指定します。
whereにはインタフェースを指定できます。

そこで、s をプロパティとして持つインターフェースとして定義し、Testをそのインターフェースから派生します。その際、s をプロパティへ変更する必要があります。
その上で、getReverseTest<T>関数のwhere節で指定すれば良い筈です。

結構手間がかかります。逆に、もしジェネリクスでなくても良いならば、下記で行けると思いますが、ダメだったらすいません。

string getReverseTest(Stack<Test> tests){

投稿2018/02/17 08:24

編集2018/02/17 11:18
Chironian

総合スコア23272

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

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

退会済みユーザー

退会済みユーザー

2018/02/17 10:32

ご回答ありがとうございます。フィールドですね、すみません。 追記しました。宜しくお願い致します。
catsforepaw

2018/02/17 11:35

> そこで、s をプロパティとして持つインターフェースとして定義し、Testをそのインターフェースから派生します。その際、s をプロパティへ変更する必要があります。 そんな必要はないですよ。そののままTestと書いても問題ありません。whereにはintとかlongなどの構造体も指定できます。
catsforepaw

2018/02/17 11:47

すみません。whereに構造体も書けるというのは嘘でした。以前何かで使ったような気がしたのですが勘違いだったようです。 クラスは指定できます。
Chironian

2018/02/17 13:27

おお、クラスを直接指定できるのですね! ↓最近、個人的にC++のメンバの有無チェックで盛り上がってたので頭が凝り固まってたようです。 https://goo.gl/2rFbK1 フォローありがとうです。
guest

0

ベストアンサー

string getReverseTest<T>(Stack<T> tests)

ジェネリックメソッドにして引数に型パラメーターを使っていますよね。これだと、このメソッド内ではStack<T>の要素の型であるTクラスが何なのかが特定されないので、そのメンバーとしてsを指定することはできません。

Stack<T>の要素の型をTestクラスと想定しているのなら、そもそもジェネリックにせずに

C#

1string getReverseTest(Stack<Test> tests)

これで良いと思うのですが。

もしどうしてもジェネリックにしたいのなら、

C#

1string getReverseTest<T>(Stack<T> tests) where T : Test

このようにすれば、ジェネリックメソッド内でTクラスがTestクラスと想定できるので、sにアクセスできるようになります(whereに渡すクラスが1個のみではジェネリックの意味はないですが)。

投稿2018/02/17 11:24

編集2018/02/17 11:26
catsforepaw

総合スコア5938

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

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

退会済みユーザー

退会済みユーザー

2018/02/17 11:50

ご回答ありがとうございます。 Testクラスと想定しているので、ジェネリックをやめました。 しかし、まだエラーが表示されます。 ご教授のほどお願い致します。
catsforepaw

2018/02/17 11:55

> string getReverseTest(Stack<Test> tests) よく見てください。メソッド名の横には<Test>は付いていませんよ。
退会済みユーザー

退会済みユーザー

2018/02/17 11:59

ご回答ありがとうございます。 失礼しました。 コンパイルが通りました。 ご教授いただきありがとうございました。
guest

0

s が外部参照できない private なのが原因で public にする内容の回答を考えていたのですが、

※やりたいことを質問用に簡素化したのがTestクラスです。
Stackの要素に直接stringを入れる仕様は考えていません。

この内容より、ひょっとしたら、

class Test { public string s { get; private set; } public Test(string b) { this.s = b; } }

が、いいかもしれません。推測が間違ってたらすみません...

投稿2018/02/17 09:16

GuielNo4

総合スコア88

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

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

退会済みユーザー

退会済みユーザー

2018/02/17 10:32

ご回答ありがとうございます。 追記しました。宜しくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問