44427
以下のコードでbメソッドで取得した引数testのプロパティを1つのみ取得したいのですが、実現可能でしょうか？よろしくお願いいたします。

```

        public void a()
        {
            b<test>(new test{ a = 1 });
        }
    
        public void b<T>(T test)
        {
            // test.GetType().GetProperties()にて取得できる値が以下
            // {System.Reflection.PropertyInfo[2]}
            // [0] [PropertyInfo]:{Int32 a}
            // [1] [PropertyInfo]:{System.String b}
    
            // 本当は引数で指定した値のみ取得したい！
            // {System.Reflection.PropertyInfo[1]}
            // [0] [PropertyInfo]:{Int32 a}
        }
    
        class test
        {
            public int a { get; set; }
            public string b { get; set; }
        }
    
```
CC BY-SA 4.0
2018-05-31T07:36:15.773
44426
2018-05-31T08:05:07.633
24385
question
c# .net asp.net
ジェネリックの引数で作られているメソッドに指定したオブジェクトのプロパティのみ取得する方法
前提としてC#では呼び出し元でどのような処理を行っているか呼び出し側から判定することは出来ません。ですので正確に判断する方法はありません。

ですが.NET
Frameworkには`PropertyDescriptor`という仕組みがあり、これによって特定のプロパティが変更されているかどうかを知ることが出来ます。まずプロパティの定義に既定の値を

```

    using System.ComponentModel;
    class test
    {
        [DefaultValue(0)]
        public int a { get; set; }
    
        [DefaultValue(null)]
        public string b { get; set; }
    }
    
```

のように`DefaultValueAttribute`で指定しておけば、`PropertyDescriptor.ShouldSerializeValue`でこの値から変更されているかどうかが分かりますので、これを利用して

```

    public void a()
    {
        b<test>(new test { a = 1 });
        b<test>(new test { b = "1" });
        b<test>(new test { a = 0, b = null });
    }
    
    public void b<T>(T test)
    {
        var properties = TypeDescriptor.GetProperties(test);
        var pd = properties.Cast<PropertyDescriptor>()
                            .FirstOrDefault(p => p.ShouldSerializeValue(test));
        Console.WriteLine(pd?.Name ?? "null");
    }
    
```

のように`ShouldSerializeValue`が`true`となっているプロパティを探すことが出来ます。ただ最後の例のように既定値自体が設定されている場合は`false`となりますので、これを検出するにはプロパティの`set`でフラグを立ててやるような実装が必要になるかと思います。
CC BY-SA 4.0
2018-05-31T08:05:07.633
44427
2018-05-31T08:05:07.633
5750
44426
answer