@Glebster13

Как вывести список всех свойств и всё что с ними связано?

Задание по рефлексии, я в ней вообще не разбираюсь. Итак, задание следующее:

Вывести список всех методов и их тип и входные параметры. Также вывести список всех свойств, их тип, значение отметки get set.
При этом сделать атрибут, пометив который в свойство/метод, они не выводятся. (Как я понял, это поле boolean)


Я кое-как написал код для вывода списка методов, но без проверки наличия/отсутствия ключевого поля. Вот мой код:
using System;
using System.Reflection;

namespace ConsoleApp3
{
    
    class ReflectClass //тут пишутся методы для вывода
    {
        double d, f;
        public ReflectClass(double d, double f)
        {
            this.d = d;
            this.f = f;

        }
        public double MyTest(double d, double f)
        {
            return d + f;

        }
        public void Set(double d, double f)
        {
        }

        public static void MethodReflectInfo<T>(T obj) where T: class //конкретно тут танцы с рефлексией
        {
            Type t = typeof(T);
            MethodInfo[] MArr = t.GetMethods();
            Console.WriteLine("Список методов класса {0}\n", obj.ToString());
            foreach (MethodInfo m in MArr)
            {
                
                Console.Write("-->"+m.ReturnType.Name + " \t" + m.Name + "(");
                ParameterInfo[] p = m.GetParameters();
                for (int i = 0; i < p.Length; i++)
                {
                    Console.Write(p[i].ParameterType.Name + " " + p[i].Name);
                    if (i + 1 < p.Length)
                    {
                        Console.Write(", ");
                    }
                }
                Console.Write(")\n");
            }
        }
    }
    class Program
    {
        static void Main(string[] args) //точка входа в программу
        {
            ReflectClass mts = new ReflectClass(12.0, 3.5); //вызов метода
            ReflectClass.MethodReflectInfo<ReflectClass>(mts); //что то непонятное
            Console.ReadLine();
        }
    }
}


Пожалуйста, реализуйте проверку наличия/отсутствия этого булевого поля при выводе списка методов и переделайте код под перечисление свойств (тоже с проверкой булевого поля).
  • Вопрос задан
  • 296 просмотров
Решения вопроса 1
@Glebster13 Автор вопроса
Всем привет, я сам пришёл к решению. Выкладываю решение своего же вопроса, вдруг кому пригодится.
using System;
using System.Reflection;
using System.Linq;

namespace _123
{
    [AttributeUsage((AttributeTargets.Method))] //атрибут на метод
    public class HiddenMethod : System.Attribute
    {

    }
    [AttributeUsage((AttributeTargets.Property))] //атрибут на свойство
    public class HiddenProperty : System.Attribute
    {

    }//Вообще атрибуты сверху можно заменить одним, 
     //просто в качестве параметра AttributeUsage прописать 
     //(AttributeTargets.Method || AttributeTargets.Property)
    public class ReflectClass //перечисление методов и свойств
    {
        double d, f;
        [HiddenProperty]
        public string DefaultMessage { get; set; } = "Hello world"; //Свойства

        public string SecondMessage { get; set; } = "Hi";

        public string ThirdMessage { get; set; } = "Bye";
        public ReflectClass(double d, double f) //к конструктору нельзя применять атрибуты
        {
            this.d = d;
            this.f = f;
        }
        public double MyTest(double d, double f) //Методы
        {
            return d + f;
        }
        [HiddenMethod]
        public void Set1(double d, double f)
        {

        }
        public void Set2(double d, double f)
        {

        }
        public void Set3(double d, double f)
        {

        }
        public static void MethodReflectInfo<T>(T obj) where T : class //основной класс
        {
            Type t = typeof(T);//Определение типа
            Console.WriteLine("Список методов класса {0}\n", obj.ToString());
            var meths = t.GetMethods().Where(p => !p.GetCustomAttributes<HiddenMethod>().Any() && !p.Name.Contains("get_") && !p.Name.Contains("set_")).ToList();
            foreach (MethodInfo m in meths) //поиск методов
            {
                //if ((!(m.GetCustomAttribute<HiddenMethod>() == null)) && (!(m.Name.Contains("_get"))) && (!(m.Name.Contains("_set"))))//проверка
                //{
                    Console.Write("-->" + m.ReturnType.Name + " \t" + m.Name + "(");
                    ParameterInfo[] p = m.GetParameters();
                    for (int i = 0; i < p.Length; i++)
                    {
                        Console.Write(p[i].ParameterType.Name + " " + p[i].Name);
                        if (i + 1 < p.Length)
                        {
                            Console.Write(", ");
                        }
                    }
                    Console.Write(")\n");
                //}
            }
            Console.WriteLine("Список свойств класса {0}\n", obj.ToString());
            var props = t.GetProperties().Where(p => !p.GetCustomAttributes<HiddenProperty>().Any()).ToList();
            foreach (PropertyInfo m in props) //поиск свойств
            {

                //if (((m.GetCustomAttribute<HiddenProperty>() != null)) || (m.Name.Contains("_get") || (m.Name.Contains("_set"))))//проверка
                //{
                    Console.Write("-->" + " \t" + m.Name + " \t" + " Can read:" + m.CanRead + " \t" + " Can write:" + m.CanWrite);
                    Console.Write("\n");
                //}
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ReflectClass mts = new ReflectClass(12.0, 3.5);
            ReflectClass.MethodReflectInfo<ReflectClass>(mts);
            Console.ReadLine();

        }
    }
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
vabka
@vabka Куратор тега C#
Токсичный шарпист
При этом сделать атрибут, пометив который в свойство/метод, они не выводятся. (Как я понял, это поле boolean)

Почему ты подумал, что это какое-то поле, если атрибуты - это вполне конкретная конструкция языка? (https://docs.microsoft.com/en-us/dotnet/csharp/pro...)
Вот пример, как его можно использовать:
var type = typeof(Test);

var members = type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
foreach (var member in members)
{
    if (member.GetCustomAttribute<IgnoreItAttribute>() is null) // Проверяем, что атрибут IgnoreIt не стоит
    {

        var str = member switch
        {
            MethodInfo method => FormatMethod(method),
            _ => null
        };
        if (str is not null)
            Console.WriteLine(str);
    }
}
static string FormatMethod(MethodInfo method) => method.ToString();

class IgnoreItAttribute : Attribute { }
class Test
{
    public void Method1() { }
    [IgnoreIt]
    public int Method2(int a, int b) => 0;
}


их тип и входные параметры

В таком случае весь твой код по форматированию метода можно заменить одной строчкой:
Console.WriteLine(m.ToString());
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы