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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C#

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

Q&A

解決済

4回答

2270閲覧

クラス名(非インスタンス).プロパティ名でプロパティの情報を引数として使用できるようにする方法

hirotamasami

総合スコア5

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C#

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

0グッド

0クリップ

投稿2020/10/14 08:36

編集2020/10/14 08:47

前提・実現したいこと

C#のプロパティについてですが、
プロパティを非静的に定義した場合
それらをインスタンス化することで
そのプロパティの値を取得することができると思います。
そこでこれらのプロパティをインスタンスに左右されない形で取得する時、
インスタンス無しでプロパティ(もちろん値以外)を
クラス名(非インスタンス).プロパティ名
のように使用したいんですが何か方法はありますでしょうか?

例えばnameof演算子を使用する時、
下記のように使用できるのですが、

C#

1 public class FreeClass 2 { 3 public string FreeProperty { get; set; } 4 } 5 6 public class UserClass 7 { 8 public void UseNameof() 9 { 10 string name = nameof(FreeClass.FreeProperty); 11 } 12 }

本来できないはずの使い方
クラス名(非インスタンス).プロパティ名
の形で引数で使用することができます。

このようにプロパティの値を使用するわけでは無ければ、
何か引数に制限や制約を付けたりすることで
クラス名(非インスタンス).プロパティ名
の形を引数で使用できるメソッドを作成したいのですが、
どのように実装すればよろしいでしょうか?

このようなサイトでの質問もまだ慣れておらず、情報不足ありましたら
ご指摘ください。
宜しくお願い致します。

実現したいこと

・下記のようなメソッドを用意し、呼び出す側はこのメソッドの引数を
クラス名(非インスタンス).プロパティ名でしか使用できないようにしたい

C#

1 public class FreeManagerClass 2 { 3 public static void FromPropertyMethod(/* クラス名(非インスタンス).プロパティ名で */) 4 { 5       6 //プロパティの情報を用いて処理 7 } 8 } 9 10 public class UserClass 11 { 12 public void UseFromPropertyMethod() 13 { 14 FreeManagerClass.FromPropertyMethod(/* クラス名(非インスタンス).プロパティ名で */) 15 } 16 }

※プロパティ名を取得したいわけではありません。
インスタンスからPropertyInfoを取得できるのは存じておりますが、
メソッドを使う側ではnameofの引数のように簡潔に記述できるようにしたい
PropertyInfoを利用するのはもちろん大丈夫ですが、
仮に使用する場合、
それをユーザーサイドから実装しなくてもよく
なおかつユーザーがそのメソッドを使用する場合
クラス名(非インスタンス).プロパティ名
の形にしたいというのが今回の質問になります。

仮にPropertyInfoを使用する場合の避けたい例

C#

1 public class FreeClass 2 { 3 public string FreeProperty { get; set; } 4 } 5 6 public class FreeManagerClass 7 { 8 public static void FromPropertyMethod(PropertyInfo propertyInfo) 9 { 10 //propertyInfoを用いて処理 11 } 12 } 13 14 public class UserClass 15 { 16 public void UseFromPropertyMethod() 17 { 18       PropertyInfo propertyInfo //何らかの方法でユーザーから取得してもらう 19 FreeManagerClass.FromPropertyMethod(propertyInfo) 20 } 21 } 22 23

仮にPropertyInfoを使用する場合の理想例

C#

1 public class FreeClass 2 { 3 public string FreeProperty { get; set; } 4 } 5 6 public class FreeManagerClass 7 { 8 public static void FromPropertyMethod(/* クラス名(非インスタンス).プロパティ名で */) 9 { 10       PropertyInfo propertyInfo ///クラス名(非インスタンス).プロパティ名でPropertyInfoを取得する 11 //プロパティの情報を用いて処理 12 } 13 } 14 15 public class UserClass 16 { 17 public void UseFromPropertyMethod() 18 { 19 FreeManagerClass.FromPropertyMethod(FreeClass.FreeProperty/* クラス名(非インスタンス).プロパティ名で */) 20 } 21 } 22 23

補足情報(FW/ツールのバージョンなど)

・OS バージョン Windows10

・nameof演算子の仕組みなどがわかればかなり
知りたいことに近い感じになります。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/10/15 04:31 編集

言語仕様として出来ませんが、何故そのような事がしたいのかの目的を具体的に書けば代替案が出てくるかもしれません。(あまりトリッキーな設計をするとメンテナンスに苦労しそうなので、設計を見直した方がいい気はしますが)
BluOxy

2020/10/15 04:41

なぜPropertyInfoを使うのでしょうか。コードの臭いがします。
guest

回答4

0

nameof演算子の仕組みなどがわかればかなり知りたいことに近い感じになります。

残念ながら、nameof言語組み込みの機能で、文法段階で対応する仕組みが組み込まれています(MSDN)。一般のメソッドの引数に、FreeClass.FreePropertyのようなものを渡すことはできません。

投稿2020/10/14 09:05

maisumakun

総合スコア146018

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

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

hirotamasami

2020/10/19 06:01

回答ありがとうございます。 whereやら属性やらを駆使すれば、 何か方法があるのかと 思っておりましたが、 やはり方法はないんですね。 今後のC#のグレードアップに期待します。 ありがとうございます。
guest

0

ベストアンサー

例えば式木を使用するとかはどうでしょうか?
目的がいまいち伝わらないので的外れかもしれませんが...

C#

1public class FreeClass { 2 public string FreeProperty { get; set; } 3} 4 5public class FreeManagerClass { 6 7 private static Func<FreeClass, object> TargetProperty; 8 9 public static void FromPropertyMethod( 10 System.Linq.Expressions.Expression<Func<FreeClass, object>> expression) { 11 12 TargetProperty = expression.Compile(); 13 } 14 15 // 値取得時には対象インスタンスを受け取って実行 16 public object GetValue(FreeClass instance) { 17 return TargetProperty.Invoke(instance); 18 } 19} 20 21public class UserClass { 22 23 public void UseFromPropertyMethod() { 24 FreeManagerClass.FromPropertyMethod(x => x.FreeProperty); 25 } 26 27}

投稿2020/10/15 00:33

編集2020/10/15 00:35
dekaaki

総合スコア292

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

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

gentaro

2020/10/15 05:31 編集

勘違いかもしれないので削除
dekaaki

2020/10/15 02:08

インスタンスを参照したくないという趣旨に関しては使い方が分からなかったのであくまでインスタンスの値を取得する場合はインスタンスを渡す例を書いたまでで FreeManagerClass.FromPropertyMethod(x => x.FreeProperty); の時点ではインスタンスを使用していませんがそれでも趣旨に反しているということでしょうか?
gentaro

2020/10/15 02:54

あー、微妙ですね。こちらの理解が間違っていたかもしれません。 というか、質問文の趣旨については私の理解と質問者の意図が合ってるのかどうかもわからないため、余計なお世話だったような気がしますので、上記コメントは撤回します。
dekaaki

2020/10/15 03:17

いえいえ。こちらも何らかの勘違いがあってはいけないので聞いたまでです。 ありがとうございました。
hirotamasami

2020/10/19 06:00

回答ありがとうございます。 式木を使用することで、 文字列などの不安定指定の仕方をせず わざわざ無駄なインスタンスを使用せずにすむというわけですね まだざっくりプロパティの名前やLinqなどで使用するくらいしか考えてませんが、 式木の使い方を確認し おっしゃっていただいた方法で 上記のものの取得や使用が可能なら こちらを参考に進めさせていただきます。 ありがとうございます。 また何かございましたら、 よろしくお願いします。
guest

0

インスタンス無しでプロパティ(もちろん値以外)を

クラス名(非インスタンス).プロパティ名
のように使用したい

文字列によるアクセスにはなりますが、下記が一番単純だと思います。
インスタンス生成なしでは、文字列によるアクセスしかできません。

C#

1var p = typeof(FreeClass).GetProperty("FreeProperty"); 2FreeManagerClass.FromPropertyMethod(p);

生成あり

C#

1var f = new FreeClass(); 2var p = typeof(f).GetProperty(f.FreeProperty); 3FreeManagerClass.FromPropertyMethod(p);

もしくは How to get the PropertyInfo of a specific property?PropertyHelper<T> が便利そうです。

C#

1var p = PropertyHelper<FreeClass>.GetProperty(x => x.FreeProperty); 2FreeManagerClass.FromPropertyMethod(p);

そもそも論にはなりますが、目的次第ではPropertyInfoを使う必要はありません。
というよりも、それがほとんどでしょう。

PropertyInfonameofのようなメタデータへのアクセス(リフレクション)は動作が遅かったり、実行時に例外が出てデバッグし辛くなったりで、使いどころを選ばないとリフレクションのデメリットばかりが目立つだけになります。

投稿2020/10/15 04:55

編集2020/10/15 06:28
BluOxy

総合スコア2663

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

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

退会済みユーザー

退会済みユーザー

2020/10/15 06:22

重箱の隅かもしれませんが - nameof 式 (C# リファレンス) https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/nameof > nameof 式を使うと、変数、型、またはメンバーの名前が文字列定数として生成されます。 > nameof 式はコンパイル時に評価され、実行時には影響を与えません。 上記の通り、nameof 式はリフレクションではありません。 コンパイル時なので、使用したからといって動作が遅くなったり、 実行時に例外が出てというのは当てはまらないでしょう。
BluOxy

2020/10/15 06:27

コンパイル時なんですね。勉強になりました。内容を訂正します。 コメントありがとうございます。
hirotamasami

2020/10/19 05:53

回答ありがとうございます。 まだ具体的に、 なにに使用するかなどは決まっておらず、 nameof演算子の例の使い方を見た時もしかしたら可能かと考えた次第になります。 例にPropertyInfoを用いたのは、 考えとして省きたい部分などを記述することで 一応遠回りになってしまうのを避けるために記述しただけで 特にPrropetyInfoにこだわりなどはありません。 ※効果があったかはわかりませんが しかしPropertyHelper<T>なるものが存在するんですね 参考にさせていただきます。 ありがとうございます。
guest

0

質問に対する回答としては、maisumakunさんの仰る通りです。

ちなみに、今回の質問のようにプロパティ名を引数として渡したい場合、nameof演算子を使う前提でstring型になっている場合が多いように感じます(WPFのDependencyPropertyなど)。
実装される際のご参考までに。

投稿2020/10/14 12:07

Automatic9045

総合スコア313

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

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

hirotamasami

2020/10/19 06:00

回答ありがとうございます。 他の機能を組み合わせてそれっぽいものを 作成して、だましだまし使っていきます。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問