4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ひとりでAdvent Calendar 2019

Day 13

C# Reflection

Last updated at Posted at 2019-12-12

やれると便利なリフレクション。
csvから適当にデータ作ったり、データを見たり
後はDTOのフィールド数が多いときとかに便利。

###Type取得

Program.cs
using System;

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            var fruit = new Fruit();
            Console.WriteLine(fruit.GetType());
        }
    }

    public class Fruit
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Price { get; set; }

        public int Number { private get; set; }
    }
}

実行結果

ConsoleApp9.Fruit

###フィールド名取得

Program.cs
using System;

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            var fruit = new Fruit();
            foreach(var prop in fruit.GetType().GetProperties())
            {
                Console.WriteLine(prop.Name);
            }
        }
    }

    public class Fruit
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Price { get; set; }

        public int Number { private get; set; }
    }
}

実行結果

Id
Name
Price
Number

###get,setの存在
setter,getterがあるかは、CanWrite,CanReadのフィールドで見ることができる。

Program.cs
using System;

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            var fruit = new Fruit();
            foreach(var prop in fruit.GetType().GetProperties())
            {
                Console.WriteLine("propName = {0}, Write = {1}", prop.Name, prop.CanWrite);
            }
        }
    }

    public class Fruit
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Price { get; set; }

        public int Number { get; } = 1;
    }
}

実行結果

propName = Id, Write = True
propName = Name, Write = True
propName = Price, Write = True
propName = Number, Write = False

###アクセッサーについて。

アクセッサーの取得。

Program.cs
using System;

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            var fruit = new Fruit();
            foreach(var prop in fruit.GetType().GetProperties())
            {
                Console.WriteLine("propName = {0}, Write = {1}", prop.Name, prop.GetAccessors()[0].Name);
            }
        }
    }

    public class Fruit
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Price { get; set; }

        public int Number { get; set; } = 1;
    }
}

実行結果

propName = Id, Write = get_Id
propName = Name, Write = get_Name
propName = Price, Write = get_Price
propName = Number, Write = get_Number

Numberのgetterをprivateにすると...?

Program.cs
using System;

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            var fruit = new Fruit();
            foreach(var prop in fruit.GetType().GetProperties())
            {
                Console.WriteLine("propName = {0}, Write = {1}", prop.Name, prop.GetAccessors()[0].Name);
            }
        }
    }

    public class Fruit
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Price { get; set; }

        public int Number { private get; set; } = 1;
    }
}

実行結果

propName = Id, Write = get_Id
propName = Name, Write = get_Name
propName = Price, Write = get_Price
propName = Number, Write = set_Number

ここだけset_Numberとなっている。

###Refrection 値取得

Fr.GetType().GetProperties()を実行した瞬間Fruitのフィールドの情報となっている。
prop.GetValueメソッドによって間接的に値を取得している。

Program.cs
using System;
using System.Collections.Generic;

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            var Fruit1 = new Fruit(1, "apple", 180, 5);
            var Fruit2 = new Fruit(2, "banana", 220, 7);
            var Fruit3 = new Fruit(3, "cherry", 210, 6);

            var Fruits = new List<Fruit>() { Fruit1, Fruit2, Fruit3 };
            foreach(var Fr in Fruits)
            {
                var props = Fr.GetType().GetProperties();
                foreach(var prop in props)
                {
                    Console.WriteLine("PropName = {0}, PropValue = {1}", prop.Name, prop.GetValue(Fr));
                }
                Console.WriteLine("**********************");
            }
        }
    }

    public class Fruit
    {
        public Fruit(int Id, string Name, int Price, int Number)
        {
            this.Id = Id;
            this.Name = Name;
            this.Price = Price;
            this.Number = Number;
        }

        public int Id { get; set; }
        public string Name { get; set; }
        public int Price { get; set; }
        public int Number { get; set; } = 1;
    }
}

実行結果

PropName = Id, PropValue = 1
PropName = Name, PropValue = apple
PropName = Price, PropValue = 180
PropName = Number, PropValue = 5
**********************
PropName = Id, PropValue = 2
PropName = Name, PropValue = banana
PropName = Price, PropValue = 220
PropName = Number, PropValue = 7
**********************
PropName = Id, PropValue = 3
PropName = Name, PropValue = cherry
PropName = Price, PropValue = 210
PropName = Number, PropValue = 6
**********************

###Refrection 値セット

prop.SetValue(a, b)によってaのprop.Name(フィールド名)をbに変更する。
下の場合だとFrオブジェクトのNameフィールドを"test"に変更する。
上の実行結果と見比べてみるときちんと値がセットされていることが分かる。

Program.cs
using System;
using System.Collections.Generic;

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            var Fruit1 = new Fruit(1, "apple", 180, 5);
            var Fruit2 = new Fruit(2, "banana", 220, 7);
            var Fruit3 = new Fruit(3, "cherry", 210, 6);

            var Fruits = new List<Fruit>() { Fruit1, Fruit2, Fruit3 };


            foreach(var Fr in Fruits)
            {
                var props = Fr.GetType().GetProperties();
                foreach (var prop in props)
                {
                    if (prop.Name == nameof(Fr.Name)) prop.SetValue(Fr, "test");
                }
            }

            foreach(var Fr in Fruits)
            {
                var props = Fr.GetType().GetProperties();
                foreach(var prop in props)
                {
                    Console.WriteLine("PropName = {0}, PropValue = {1}", prop.Name, prop.GetValue(Fr));
                }
                Console.WriteLine("**********************");
            }
        }
    }

    public class Fruit
    {
        public Fruit(int Id, string Name, int Price, int Number)
        {
            this.Id = Id;
            this.Name = Name;
            this.Price = Price;
            this.Number = Number;
        }

        public int Id { get; set; }
        public string Name { get; set; }
        public int Price { get; set; }
        public int Number { get; set; } = 1;
    }
}

実行結果

PropName = Id, PropValue = 1
PropName = Name, PropValue = test
PropName = Price, PropValue = 180
PropName = Number, PropValue = 5
**********************
PropName = Id, PropValue = 2
PropName = Name, PropValue = test
PropName = Price, PropValue = 220
PropName = Number, PropValue = 7
**********************
PropName = Id, PropValue = 3
PropName = Name, PropValue = test
PropName = Price, PropValue = 210
PropName = Number, PropValue = 6
**********************
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?