powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Преобразовать MySuperClass<class> в MySuperClass<interface>
12 сообщений из 12, страница 1 из 1
Преобразовать MySuperClass<class> в MySuperClass<interface>
    #38188747
Alex Shulg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет! Помогите, запутался...
Имеем:
Код: c#
1.
2.
3.
4.
5.
6.
7.
public class MySuperClass<T> : where T : class, IMyInterface { ... }
public class MyClass1: IMyInterface { ... }
public class MyClass2: IMyInterface { ... }

MySuperClass<MyClass1> myClass1 = new MySuperClass<MyClass1>();
...
MySuperClass<IMyInterface> myClass2 =  myClass1 as MySuperClass<IMyInterface>;



В итоге myClass2 == null. Собственно вопрос, как побороть?
Проблема в том, что я в определенном месте получаю в виде object MySuperClass<MyClassX>, где MyClassX - один из классов, наследующих IMyInterface. Зная, что данный интерфейс у них общий, я и хочу получить доступ к телу MySuperClass, но перечислять все возможные проверки типа
Код: c#
1.
2.
if (myClass is MySuperClass<MyClass1>) {...}
else if (myClass is MySuperClass<MyClass2>) {...}

не хочется.
Заранее благодарю за помощь.
...
Рейтинг: 0 / 0
Преобразовать MySuperClass<class> в MySuperClass<interface>
    #38188785
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex ShulgВ итоге myClass2 == null. Собственно вопрос, как побороть?
А, по-моему, это вообще компилиться не будет.

http://msdn.microsoft.com/ru-ru/library/dd469487.aspx
...
Рейтинг: 0 / 0
Преобразовать MySuperClass<class> в MySuperClass<interface>
    #38188814
Фотография Esofter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а зачем тебе делать эти проверки? вызывай интерфейсный метод.
вызов будет полиморфным и выполнится нужный код.

определеяем интерфейс, классы реализации и обобщенный класс

Код: 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.
public interface IExample
    {
        void DoSmth();
    }

    public class Example1 : IExample
    {
        public void DoSmth()
        {
            Console.WriteLine("Example 1");
        }
    }

    public class Example2 : IExample
    {
        public void DoSmth()
        {
            Console.WriteLine("Example 2");
        }
    }

    public class SuperExample<T>  where T : class, IExample
    {
        public IExample Instance { get; private set; }

        public SuperExample(T instance)
        {
            this.Instance = instance;
        }
    }



Пишем метод, который ожидает интерфейс, ему должно быть наплевать какая реализация пришла.

Код: c#
1.
2.
3.
4.
 public static void DoSmth(IExample example)
        {
            example.DoSmth();
        }



Пример использования. Не надо никакой проверки типов, вызовется то, что нужно

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
public static void Main(string[] args)
        {
            var ex1 = new SuperExample<Example1>(new Example1());
            var ex2 = new SuperExample<Example2>(new Example2());

            DoSmth(ex1.Instance);
            DoSmth(ex2.Instance);
        }
...
Рейтинг: 0 / 0
Преобразовать MySuperClass<class> в MySuperClass<interface>
    #38188968
Alex Shulg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сорри, видать плохо пояснил, чего хочу. Попробую продемонстрировать на примере Esofter:
Код: 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.
public class SuperExample<T>  where T : class, IExample
{
        public void SuperExampleDoSmth()
        {
            
        }
}

public static void Main(string[] args)
{
     var ex1 = new SuperExample<Example1>(new Example1());
     var ex2 = new SuperExample<Example2>(new Example2());

     DoSmth(ex1);
     DoSmth(ex2);
}

// здесь параметр именно object !!!
public static void DoSmth(object example)
{
     // здесь я хочу вызвать SuperExampleDoSmth
     // я знаю, что object это SuperExample<Example1> или SuperExample<Example2>
     // хочу нечто такое:
     (object as SuperExample<IExample>).SuperExampleDoSmth();
}


Чего-то пока писал, пришла мысль попробовать вообще иначе всё это реализовать... Но, тем не менее, было бы интересно услышать ответ на свой вопрос: возможно ли? как?
...
Рейтинг: 0 / 0
Преобразовать MySuperClass<class> в MySuperClass<interface>
    #38189011
SerP1983
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тынц

Код: 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.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var ex1 = new SuperExample<Example1>(new Example1());
            var ex2 = new SuperExample<Example2>(new Example2());

            DoSmth(ex1);
            DoSmth(ex2);

            Console.ReadKey();
        }

        // здесь параметр именно object !!!
        public static void DoSmth(object example)
        {
           // здесь я хочу вызвать SuperExampleDoSmth
           // я знаю, что object это SuperExample<Example1> или SuperExample<Example2>
           // хочу нечто такое:
           (example as ISuperExample<IExample>).SuperExampleDoSmth();
        }
    }

    public interface IExample
    {
        void DoSmth();
    }

    public class Example1 : IExample
    {
        public void DoSmth()
        {
            Console.WriteLine("Example 1");
        }
    }

    public class Example2 : IExample
    {
        public void DoSmth()
        {
            Console.WriteLine("Example 2");
        }
    }

    public interface ISuperExample<out T> where T : class, IExample
    {
        void SuperExampleDoSmth();
    }

    public class SuperExample<T> : ISuperExample<T> where T : class, IExample
    {
        public IExample Instance { get; private set; }

        public SuperExample(T instance)
        {
            this.Instance = instance;
        }

        public void SuperExampleDoSmth()
        {
            Console.WriteLine("SuperExampleDoSmth: " + typeof(T).Name);
        }
    }
}

...
Рейтинг: 0 / 0
Преобразовать MySuperClass<class> в MySuperClass<interface>
    #38189188
Alex Shulg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ок, SerP1983

Мысль понятно. Еще усложним?

Код: c#
1.
2.
3.
4.
5.
6.
public interface ISuperExample<out T> where T : class, IExample
{
     void SuperExampleDoSmth();

     IEnumerable<T> Items { get; set; }
}


Ошибка
Недопустимое изменение. Параметр типа "T" должен быть контравариантно действителен в "ISuperExample<T>.Items". "T" является ковариантный.

Как с этим бороться?
...
Рейтинг: 0 / 0
Преобразовать MySuperClass<class> в MySuperClass<interface>
    #38189256
Фотография pation
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex ShulgОк, SerP1983

Мысль понятно. Еще усложним?

Код: c#
1.
2.
3.
4.
5.
6.
public interface ISuperExample<out T> where T : class, IExample
{
     void SuperExampleDoSmth();

     IEnumerable<T> Items { get; set; }
}



Ошибка
Недопустимое изменение. Параметр типа "T" должен быть контравариантно действителен в "ISuperExample<T>.Items". "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.
        public interface IExample
        {}

        public interface ISuperExample
        {
            void SuperExampleDoSmth();
        }

        public class SuperExample<T>: ISuperExample
            where T: class, IExample
        {
            public void SuperExampleDoSmth()
            {}
        }

        // здесь параметр именно object !!!
        public static void DoSmth(ISuperExample example)
        {
            // здесь я хочу вызвать SuperExampleDoSmth
            // я знаю, что object это SuperExample<Example1> или SuperExample<Example2>
            // хочу нечто такое:
            example.SuperExampleDoSmth();
        }
...
Рейтинг: 0 / 0
Преобразовать MySuperClass<class> в MySuperClass<interface>
    #38189258
SerP1983
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во вам неймется, separated interface рулит

Код: 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.
    public interface ISuperExample<out T> where T : class, IExample
    {
        void SuperExampleDoSmth();        
    }

    interface IEnumerableContainer<T>
    {
        IEnumerable<T> Items { get; set; }
    }

    public class SuperExample<T> : IEnumerableContainer<T>, ISuperExample<T> where T : class, IExample
    {
        public IExample Instance { get; private set; }

        public SuperExample(T instance)
        {
            this.Instance = instance;
            Items = new List<T> { instance };
        }

        public void SuperExampleDoSmth()
        {
            Console.WriteLine("SuperExampleDoSmth: " + typeof(T).Name);
        }

        public IEnumerable<T> Items { get; set; }
    }
...
Рейтинг: 0 / 0
Преобразовать MySuperClass<class> в MySuperClass<interface>
    #38189285
Alex Shulg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
pation

Точно, сам допёр :)
Всем спасибо!
"Одна голова - хорошо, а две/три - лучше" :)
...
Рейтинг: 0 / 0
Преобразовать MySuperClass<class> в MySuperClass<interface>
    #38189293
SerP1983
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А я тут стараюсь: "здесь параметр именно object !!!"
...
Рейтинг: 0 / 0
Преобразовать MySuperClass<class> в MySuperClass<interface>
    #38189338
Alex Shulg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
не, ты натолкнул меня на мысль, что в исходном интерфейсе (где <out T>) надо создать заглушку метода, реализовать ее в основном интерфейсе и из кода вызывать эту заглушку, не пытаясь получить доступа к полям/методам интерфейса...
Во!
...
Рейтинг: 0 / 0
Преобразовать MySuperClass<class> в MySuperClass<interface>
    #38189346
Alex Shulg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SerP1983А я тут стараюсь: "здесь параметр именно object !!!"
Ну ты вообще, главное направление подсказал: выделение "исходного" интерфейса с <out T>
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Преобразовать MySuperClass<class> в MySuperClass<interface>
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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