質問

私は約500人の文字列メンバーを含むクラスを持っています、私はそれらをstring.emptyに設定することにより、それらすべてを「リセット」したいと思います。すべての文字列メンバーを繰り返すことができるように、リフレクションを使用してこれを行う方法を教えてもらえますか?

ありがとう

役に立ちましたか?

解決

foreach (PropertyInfo pi in MyObj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ).ToArray() )
            {
                if (pi.PropertyType == typeof(string))
                {
                    pi.SetValue(MyObj, string.Empty, null);
                }
            }

フィールドの使用

foreach (FieldInfo fi in MyObj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ).ToArray() )
            {
                if (fi.FieldType == typeof(string))
                {
                    fi.SetValue(MyObj, string.Empty);
                }
            }

他のヒント

typeof(MyClass).GetProperties()
               .Where(p => p.PropertyType == typeof(string))
               .ToList()
               .ForEach(p => p.SetValue(myObj,string.Empty, null));

編集:

プロパティではなくフィールドを扱っている場合、それは非常に似ています

typeof(MyClass).GetFields()
               .Where(f => f.FieldType == typeof(string))
               .ToList()
               .ForEach(f => f.SetValue(myObj,string.Empty));

コンパイルされた式式 - を使用して実装された同じコード:

private static Action<TObject> CreateClearStringProperties<TObject>()
{
    var memberAccessExpressions = new List<System.Linq.Expressions.Expression>();

    System.Linq.Expressions.ParameterExpression arg = System.Linq.Expressions.Expression.Parameter(typeof(TObject), "x");

    foreach (var propertyInfo in typeof(TObject).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy))
    {
        if (propertyInfo.PropertyType == typeof(string) && propertyInfo.SetMethod != null)
        {
            var memberAccess = System.Linq.Expressions.Expression.MakeMemberAccess(arg, propertyInfo);

            var assignment = System.Linq.Expressions.Expression.Assign(memberAccess, System.Linq.Expressions.Expression.Constant(string.Empty));

            memberAccessExpressions.Add(assignment);
        }
    }

    foreach (var fieldInfo in typeof(TObject).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy))
    {
        if (fieldInfo.FieldType == typeof(string))
        {
            var memberAccess = System.Linq.Expressions.Expression.MakeMemberAccess(arg, fieldInfo);

            var assignment = System.Linq.Expressions.Expression.Assign(memberAccess, System.Linq.Expressions.Expression.Constant(string.Empty));

            memberAccessExpressions.Add(assignment);
        }
    }

    if (memberAccessExpressions.Count == 0)
        return new Action<TObject>((e) => { });

    var allProperties = System.Linq.Enumerable.Aggregate(memberAccessExpressions, System.Linq.Expressions.Expression.Block);

    return System.Linq.Expressions.Expression.Lambda<Action<TObject>>(allProperties, arg).Compile();
}

それを使用する方法の例:

Action<MyClass> clearObject = CreateClearStringProperties<MyClass>();
MyClass obj = new MyClass();
clearObject(obj);

一般的なプーリングロジックのためにそれを必要としていました。そこでは、オブジェクトがプールに戻ってきて、時代遅れの文字列オブジェクトを生き続けるべきではありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top