powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Вопрос по рефлексии
25 сообщений из 27, страница 1 из 2
Вопрос по рефлексии
    #39730369
saxix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день. Подскажите вариант реализации.
Есть экземпляр(object). Надо проверить, наследуется ли он от интерфейса IMyCollection<T>, и если наследуется, то привести его к данному типу.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace ConsoleApplication
{
    interface IMyCollection<T> where T : class
    {
        List<T> Items { get; set; }
    }

    class MyClass { }

    class MyCollection : IMyCollection<MyClass>
    {
        public List<MyClass> Items { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            #region Неизменяемый участок кода
            IList collection = new List<MyClass>();
            object context = new MyCollection();
            #endregion Неизменяемый участок кода
            var contextType = context.GetType();
            var genericTypeDefinition = contextType.GetInterfaces().Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IMyCollection<>)).Select(i => i.GetGenericArguments()[0]).ToArray();
            if (!genericTypeDefinition.Any()) return;
            {
                Type type = genericTypeDefinition.FirstOrDefault();
                var impl = (IMyCollection<type>)context; // непонятно
                if (impl != null)
                {
                    impl.Items = collection.Cast<type>().ToList(); // непонятно
                }
            }
        }
    }
}
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730408
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Непонятно, что требуется.
Чтобы привести тип к интерфейсу IMyCollection<T> этот T должен быть где-то объявлен
Он не может быть получен динамически на этапе выполнения программы, так как параметры типов должны быть известны на этапе компиляции.
Отсюда и пляшите. У вас что-то с архитектурой странное.
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730427
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в заданном примере потребность в рефлексии не нужна, зачем вы её используйте?
скорее всего автору нужен ковариантный интерфейс и речь об этом. Гугл в помощь
https://metanit.com/sharp/tutorial/3.27.php и полно другой информации.
Крайне полезная вещь, но не всегда применима и требует качественной проработки всей иерархии наследования интерфейсов
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730454
saxix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProНепонятно, что требуется.
Чтобы привести тип к интерфейсу IMyCollection<T> этот T должен быть где-то объявлен
Он не может быть получен динамически на этапе выполнения программы, так как параметры типов должны быть известны на этапе компиляции.
Отсюда и пляшите. У вас что-то с архитектурой странное.
Спасибо. Придется искать другое решение
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730457
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
saxixПридется искать другое решениеопишите задачу, может подскажем
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730466
saxix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProsaxixПридется искать другое решениеопишите задачу, может подскажем
Задача была связать DataGrid.SelectedItems (View) с таким же свойством во ViewModel (класс наследуется от интерфейса с дженериком). Решил написать универсальный метод, пошел по этому пути. Предполагал о том, что написал Shocker.Pro, но, на всякий случай, спросил. Задачу можно решить и другими путями, просто интересно было "добить" данным способом.
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730467
saxix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
saxixShocker.Proпропущено...
опишите задачу, может подскажем
Задача была связать DataGrid.SelectedItems (View) с таким же свойством во ViewModel (класс наследуется от интерфейса с дженериком). Решил написать универсальный метод, пошел по этому пути. Предполагал о том, что написал Shocker.Pro, но, на всякий случай, спросил. Задачу можно решить и другими путями, просто интересно было "добить" данным способом.
Например, вот так https://social.msdn.microsoft.com/Forums/en-US/5041c158-e48b-4efd-9f73-848a85abba83/datagrid-selecteditems-in-mvvm?forum=wpf
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730490
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WPF не очень-то заточен на работу с дженериками
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730492
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Надо вязать на IEnumerable, а потом Cast или OfType в самой модели
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730498
saxix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProНадо вязать на IEnumerable, а потом Cast или OfType в самой модели
Так тип дженерика заранее не известен. Если только сделать чтобы во всех требуемых ViewModel дженерик наследовался от одного и того же типа
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730502
saxix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
saxixShocker.ProНадо вязать на IEnumerable, а потом Cast или OfType в самой модели
Так тип дженерика заранее не известен. Если только сделать чтобы во всех требуемых ViewModel дженерик наследовался от одного и того же типа
Тоже не сработает
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730509
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
saxixТак тип дженерика заранее не известен.А я и не говорю про дженерик. Просто к IEnumerable
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730515
Addx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
saxix,

Не совсем представляю, как это возможно даже теоретически.
Как можно проверить наследование от IMyCollection<T>, если Вы не знаете T ?
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730522
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AddxКак можно проверить наследование от IMyCollection<T>, если Вы не знаете T ?Для новичка всё можно )). Как только осознаёшь, что в рантайме не бывает IMyCollection<T>, так сразу всё встает на свои места.
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730526
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Addx,
IMyCollection<out T> будет "наследовать" и IMyCollection<MyClass>, и IMyCollection<object> и все прочие классы которые наследовал MyClass
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730527
saxix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Addxsaxix,

Не совсем представляю, как это возможно даже теоретически.
Как можно проверить наследование от IMyCollection<T>, если Вы не знаете T ?
Не IMyCollection<T>, а IMyCollection<>
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730532
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman MejtesIMyCollection<out T>Проблема в том, что внутри интерфейса List<T>
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730540
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProRoman MejtesIMyCollection<out T>Проблема в том, что внутри интерфейса List<T>
значит нужно его переделать :D
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730606
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот пример с List<T>, всё работает, только чего хочет автор я так и не понял
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
//Ковариантный интерфейс для получения элементов в любом типе которые наследует T
interface IIndexedEnumerable<out T> : IEnumerable<T>
{
    T this[int index] { get; }
    int Count { get; }
}

//Контрвариантный интерфейс для добавления\удаления типов наследующих от T
interface IModifiedEnumerable<in T>
{
    void Add(T obj);
    bool Remove(T obj);
}

//Наш списочный тип наследованный от List<> с поддержкой ковариантного интерфейса
class MyList<T> : List<T>, IIndexedEnumerable<T>, IModifiedEnumerable<T>
{
    public MyList() : base() { }

    public MyList(int capacity) : base(capacity) { }

    public MyList(IEnumerable<T> source) : base(source) { }
}

//базовый класс человека
abstract class BasePerson
{
    public string Name { set; get; }
    public int Age { set; get; }
    public override string ToString()
    {
        return $"{Name},{Age}";
    }
}

//класс работника
class Employeer : BasePerson
{
    public string Title { set; get; }

    public override string ToString()
    {
        return $"{Name},{Age},{Title}";
    }
}

class Slave : BasePerson
{
    public string Nick { set; get; }
}
    
class Program
{
    static void Main(string[] args)
    {
        //Создаем коллекцию MyList
        var boxedList = new MyList<BasePerson>()
        {
            new Employeer { Name = "Roman", Age = 36, Title = "Developer" },
            new Employeer { Name = "Sofia", Age = 46, Title = "Manager" },
            new Employeer { Name = "Oleg", Age = 26, Title = "Tester" },
            new Slave {  Name = "Ivan", Age = 10, Nick = "Sharik" }
        };
        //приводим к инвариантному интерфейсу
        var invariantType = (IList<BasePerson>)boxedList;
        //Приводим коллекцию к контрвариантному интерфейсу с типом Employeer,
        //то, что в тиме есть элементы типа Slave совершенно не важно, 
        //так как интерфейс ничего не возвращает
        //это будет невозможно, если убрать in из интерфейса.
        var employeerList  = (IModifiedEnumerable<Employeer>)boxedList;
        employeerList.Add(new Employeer { Name = "Nikolay", Age = 16, Title = "Pizzaman" });
        //теперь к Slave, но можно было не мучаться и к BasePerson, это не так важно
        var slaveList = (IModifiedEnumerable<Slave>)boxedList;
        slaveList.Add(new Slave { Name = "Peter", Age = 12, Nick = "Mops" });

        //Приводим её к нашему ковариантному интерфейсу с типом object,
        //это будет невозможно сделать, если убрать из интерфейса <out ..>
        var covariantList = (IIndexedEnumerable<object>)boxedList;
        //Выводим их на экран через индекс, а не через перечислитель
        for (var i = 0; i < covariantList.Count; i++)
        {
            var item = covariantList[i];
            Console.Write(item.GetType());
            Console.Write(": ");
            Console.Write(item.ToString());
            Console.WriteLine();
        }
        Console.ReadKey(true);
    }
}
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730687
Addx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
saxixAddxsaxix,

Не совсем представляю, как это возможно даже теоретически.
Как можно проверить наследование от IMyCollection<T>, если Вы не знаете T ?
Не IMyCollection<T>, а IMyCollection<>

Что это за тип IMyCollection<> ?
Я такого не знаю.
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730699
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AddxЧто это за тип IMyCollection<> ?
Я такого не знаю.Гугли "незакрытый обобщенный тип" ))
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730714
Addx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProГугли "незакрытый обобщенный тип" ))

Не могу серьезно относится к людям, которые пишут "гугли ..."
Я могу нагуглить, что Земля плоская, и что?
Приведите объявление такого типа, и сможем его обсудить.
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730725
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AddxНе могу серьезно относится к людям, которые пишут "гугли ..."
Я могу нагуглить, что Земля плоская, и что?
Приведите объявление такого типа, и сможем его обсудить.Не могу серьезно относиться к людям, которые не прочитав про основы, даже после отсылки к ним, продолжают умничать
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730754
Addx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProНе могу серьезно относиться к людям, которые не прочитав про основы, даже после отсылки к ним, продолжают умничать

Вы не в состоянии привести простой пример, а уже пытаетесь умничать.
Если человек делает отсылки к книгам, и уж тем более, к помойке, которая называется инетом, то это означает, что сам он ничего не понимает. Он начинает увиливать, ерничать, играть словами вместо приведения простого примера в 2 строчки.
Вам не лень писать длинные посты, но трудно написать простейший пример - самому не смешно?
...
Рейтинг: 0 / 0
Вопрос по рефлексии
    #39730774
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пример написан в виде кода в самом первом посте этого топика.
Какой еще нужен пример?
Если ты никогда не видел пример незакрытого обобщенного типа, это не значит, что их не существует.
Как именно разобраться в этом вопросе я подсказку дал. Ты просто, видимо, не работал с рефлексией.

ЗЫ: Интересно, что ты скажешь, когда увидишь подобную запись:
Код: c#
1.
IDictionary<,>
...
Рейтинг: 0 / 0
25 сообщений из 27, страница 1 из 2
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Вопрос по рефлексии
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]