7

プログラムの実行でstrClassname.strPropertyName異なる値strClassnameと名前を持つようなものにアクセスする必要があります。strProperty

正しい方向に向けてください。

4

3 に答える 3

15

実行時にオブジェクトのプロパティの値を取得 (または設定) しようとしているように思えます。したがって、これを行う最も基本的な方法は次のとおりです。

public static object GetPropertyValue(object instance, string strPropertyName)
{
    Type type = instance.GetType();
    System.Reflection.PropertyInfo propertyInfo = type.GetProperty(strPropertyName);
    return propertyInfo.GetValue(instance, null);
}

...そして値を設定するには:

public static void SetPropertyValue(object instance, string strPropertyName, object newValue)
{
    Type type = instance.GetType();
    System.Reflection.PropertyInfo propertyInfo = type.GetProperty(strPropertyName);
    propertyInfo.SetValue(instance, newValue, null);
}

クラスのプロパティの名前を取得しようとしている場合は、次の関数を使用できます。

public static IEnumerable<string> GetPropertyNames(string className)
{
    Type type = Type.GetType(className);
    return type.GetProperties().Select(p => p.Name);
}

100 個のオブジェクトがあり、それぞれの Name プロパティの値を取得したいとします。これを行う関数を次に示します。

public static IEnumerable<String> GetNames(IEnumerable<Object> objects, string nameProperty = "Name")
{
    foreach (var instance in objects)
    {
        var type = instance.GetType();
        var property = type.GetProperty(nameProperty);
        yield return property.GetValue(instance, null) as string;
    }
}
于 2013-12-30T19:21:20.633 に答える
8

リフレクションを使用できます:

特定のタイプのプロパティの名前を取得するには、Type.GetProperties メソッドを使用します。メソッドは PropertyInfo オブジェクトの配列を返し、プロパティ名は PropertyInfo.Name プロパティから取得できます。すべてのプロパティのサブセットのみを取得する場合 (パブリックな静的なもののみなど)、GetProperties メソッドを呼び出すときに BindingFlags を使用します。少なくとも 2 つのフラグを指定する必要があります。1 つは Public/NonPublic から、もう 1 つは Instance/Static フラグです。BindingFlags パラメーターなしで GetProperties を使用する場合、既定のフラグは Public + NonPublic + Instance です。

次の例は、パブリック静的プロパティを取得する方法を示しています。

using System.Reflection;  // reflection namespace

// get all public static properties of MyClass type
PropertyInfo[] propertyInfos;
propertyInfos = typeof(MyClass).GetProperties(BindingFlags.Public |
                                              BindingFlags.Static);
// sort properties by name
Array.Sort(propertyInfos,
        delegate(PropertyInfo propertyInfo1, PropertyInfo propertyInfo2)
        { return propertyInfo1.Name.CompareTo(propertyInfo2.Name); });

// write property names
foreach (PropertyInfo propertyInfo in propertyInfos)
{
  Console.WriteLine(propertyInfo.Name);
}

ソース

于 2012-12-21T06:29:03.647 に答える
1

100 ほどのクラスがあり、それぞれの特定のプロパティにアクセスしたいことがわかっていて、すべてのクラスがインスタンス化されることがわかっている場合は、アクセスしたいプロパティを保持するインターフェイスを作成することを検討する必要があります。

public interface INamed
{
    Name { get; }
}

使用例:

var namedInstances = listOfClasses.Of<INamed>().Cast<INamed>();

foreach(var instance in namedInstances)
{
    var name = instance.Name;
}

一方、これらのクラスをインスタンス化する予定がなく、'Name' プロパティが static または const の場合は、代わりに次のアプローチを試すことができます。

public interface INamed { } //Marker interface

public static class GetNamedHelper
{
    private static IEnumerable<Type> GetAssemblyTypes(IEnumerable<Assembly> assemblies)
    {
        if (assemblies == null) yield break;

        foreach (var assembly in assemblies.Where(assembly => assembly != null))
        {
            IEnumerable<Type> types;
            try
            {
                types = assembly.GetTypes().Where(t => t != null);
            }
            catch (ReflectionTypeLoadException rtle)
            {
                types = rtle.Types.Where(t => t != null);
            }
            foreach (var type in types)
                yield return type;
        }
    }

    private static readonly Type namedMarkerInterface = typeof (INamed);

    public static IEnumerable<string> GetNames(params Assembly[] assemblies)
    {
        var types = GetAssemblyTypes(assemblies)
            .Where(t => t.GetInterfaces().Any(intf => intf == namedMarkerInterface));

        foreach (var type in types)
        {
            //ex. public static string Name
            var prop = type.GetProperty("Name", BindingFlags.Public | BindingFlags.Static);
            if (prop == null || !prop.CanRead) continue;
            yield return prop.GetValue(null, null) as string;

            //ex. public const string Name
            var field = type.GetField("Name", BindingFlags.Public);
            if (field == null || !field.IsStatic) continue;
            yield return field.GetValue(null) as string;
        }
    }
}

いずれにせよ、どのクラスを何のためにチェックするかを知る必要があります。

于 2012-12-21T06:58:33.990 に答える