PHPの世界から、C#を試してみることにしました。私は検索したことがありますが、これに相当する方法の答えを見つけることができないようです。
$object = new Object();
$vars = get_class_vars(get_class($object));
foreach($vars as $var)
{
doSomething($object->$var);
}
基本的にオブジェクトのリストがあります。オブジェクトは3つの異なるタイプのいずれかであり、パブリックプロパティのセットを持ちます。オブジェクトのプロパティのリストを取得し、それらをループしてからファイルに書き出すことができるようにしたいのです。これはc#のリフレクションと関係があると思いますが、それはすべて私にとって新しいことです。
どんな助けも大歓迎です。
これはそれを行う必要があります:
Type myType = myObject.GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
foreach (PropertyInfo prop in props)
{
object propValue = prop.GetValue(myObject, null);
// Do something with propValue
}
はい、反射が進むべき道です。最初に、リスト内のインスタンスのタイプ(実行時)を表す Type
NAME_ を取得します。これを行うには、GetType
name__で Object
name__メソッドを呼び出します 。これはObject
name__クラスにあるため、.NETの every オブジェクトから呼び出し可能です。すべてのタイプがObject
name__から派生しているためです( まあ、技術的には、すべてではない 、しかしそれは重要ではありませんここに)。
Type
name__インスタンスを取得したら、 GetProperties
name__メソッドを呼び出してPropertyInfo
name__のプロパティに関するランタイム情報を表す Type
NAME_ インスタンスを取得できます。
注:GetProperties
name__のオーバーロードを使用して、取得する which プロパティの分類に役立てることができます。
そこから、情報をファイルに書き出すだけです。
上記のコードを翻訳すると、次のようになります。
// The instance, it can be of any type.
object o = <some object>;
// Get the type.
Type type = o.GetType();
// Get all public instance properties.
// Use the override if you want to classify
// which properties to return.
foreach (PropertyInfo info in type.GetProperties())
{
// Do something with the property info.
DoSomething(info);
}
メソッド情報またはフィールド情報が必要な場合は、 GetMethods
NAME_ または GetFields
NAME_ メソッドのオーバーロードのいずれかをそれぞれ呼び出す必要があることに注意してください。
また、ファイルのメンバーをリストすることも1つですが、プロパティセットに基づいてロジックを駆動するためにこの情報を使用するべきではありません /。
型の実装を制御できると仮定すると、共通の基本クラスから派生するか、共通のインターフェイスを実装してそれらを呼び出す必要があります( as
NAME_ または is
NAME_ 演算子を使用して、実行時に使用している基本クラス/インターフェース)。
ただし、これらの型定義を制御せず、パターンマッチングに基づいてロジックを駆動する必要がある場合は、問題ありません。
void Test(){
var obj = new{a="aaa", b="bbb"};
var val_a = obj.GetValObjDy("a"); //="aaa"
var val_b = obj.GetValObjDy("b"); //="bbb"
}
//create in a static class
static public object GetValObjDy(this object obj, string propertyName)
{
return obj.GetType().GetProperty(propertyName).GetValue(obj, null);
}
まあ、C#でも同様です。最も単純な例の1つを次に示します(パブリックプロパティのみ):
var someObject = new { .../*properties*/... };
var propertyInfos = someObject.GetType().GetProperties();
foreach (PropertyInfo pInfo in PropertyInfos)
{
string propertyName = pInfo.Name; //gets the name of the property
doSomething(pInfo.GetValue(someObject,null));
}
プロパティ名から特定のプロパティ値を取得するには
public class Bike{
public string Name {get;set;}
}
Bike b = new Bike {Name = "MyBike"};
プロパティの文字列名から名前のプロパティ値にアクセスするには
public object GetPropertyValue(string propertyName)
{
//returns value of property Name
return this.GetType().GetProperty(propertyName).GetValue(this, null);
}
GetType-GetProperties-Linq Foreach:を使用できます。
obj.GetType().GetProperties().ToList().ForEach(p =>{
//p is each PropertyInfo
DoSomething(p);
});
以下は、IEnumerable<T>
をDataTable
の各項目ごとに1つの行を持つT
のプロパティを表す列を含むIEnumerable
に変換するために使用するものです。
public static DataTable ToDataTable<T>(IEnumerable<T> items)
{
var table = CreateDataTableForPropertiesOfType<T>();
PropertyInfo[] piT = typeof(T).GetProperties();
foreach (var item in items)
{
var dr = table.NewRow();
for (int property = 0; property < table.Columns.Count; property++)
{
if (piT[property].CanRead)
{
var value = piT[property].GetValue(item, null);
if (piT[property].PropertyType.IsGenericType)
{
if (value == null)
{
dr[property] = DBNull.Value;
}
else
{
dr[property] = piT[property].GetValue(item, null);
}
}
else
{
dr[property] = piT[property].GetValue(item, null);
}
}
}
table.Rows.Add(dr);
}
return table;
}
public static DataTable CreateDataTableForPropertiesOfType<T>()
{
DataTable dt = new DataTable();
PropertyInfo[] piT = typeof(T).GetProperties();
foreach (PropertyInfo pi in piT)
{
Type propertyType = null;
if (pi.PropertyType.IsGenericType)
{
propertyType = pi.PropertyType.GetGenericArguments()[0];
}
else
{
propertyType = pi.PropertyType;
}
DataColumn dc = new DataColumn(pi.Name, propertyType);
if (pi.CanRead)
{
dt.Columns.Add(dc);
}
}
return dt;
}
これは「やや」複雑すぎますが、実際には結果が何であるかを見るのに非常に便利です。たとえば、次のようにList<T>
を指定できます。
public class Car
{
string Make { get; set; }
int YearOfManufacture {get; set; }
}
そして、次の構造を持つDataTableが返されます。
メイク(文字列)
YearOfManufacture(int)
List<Car>
のアイテムごとに1行
この例では、オブジェクトのすべての文字列プロパティをトリミングします。
public static void TrimModelProperties(Type type, object obj)
{
var propertyInfoArray = type.GetProperties(
BindingFlags.Public |
BindingFlags.Instance);
foreach (var propertyInfo in propertyInfoArray)
{
var propValue = propertyInfo.GetValue(obj, null);
if (propValue == null)
continue;
if (propValue.GetType().Name == "String")
propertyInfo.SetValue(
obj,
((string)propValue).Trim(),
null);
}
}
これが機能することを発見していません、例えばアプリケーションオブジェクト。しかし、私は成功しました
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string rval = serializer.Serialize(myAppObj);