Можно ли «привести» объект к более специализированному объекту? - PullRequest
0 голосов
/ 27 мая 2009

Проблема в том, что мне нужно немного больше функциональности для объекта класса, который я не могу изменить (я пытаюсь добавить поддержку связывания данных). Лучшее решение, о котором я могу подумать, - это просто написать производный класс с этой функциональностью. Так что я могу использовать объекты этого класса instate. Итак, теперь проблема в том, как мне инициализировать объекты нового класса? Я мог бы создать конструктор с исходным объектом в качестве параметра и инициализировать производный объект значениями этого объекта, но мне кажется, что это не самое разумное решение. Было бы хорошо, если бы я мог сделать что-то вроде:

// MyDerivedClass is derived from ObjectOfAnUnchangeableClass.
MyDerivedClass Obj = ObjectOfAnUnchangeableClass as MyDerivedClass;  

Конечно, это не сработает, потому что ObjectOfAnUnchangeableClass не знает о MyDerivedClass. Другая идея - иметь конструктор, который можно «инициализировать» объектом. Что-то вроде:

public MyDerivedClass(UnchangeableClass obj): base(obj){}

Здесь идея состоит в том, чтобы вместо базового конструктора построить новый объект; это может просто взять существующий объект.

Итак, у меня два вопроса:

  1. Есть ли в .net какая-то концепция, поддерживающая что-то вроде упомянутого выше?
  2. Какое было бы наилучшее решение, чтобы иметь некоторые дополнительные функции в классе, которые нельзя изменить?

Ответы [ 6 ]

6 голосов
/ 27 мая 2009

Вы уже почти ответили на этот вопрос - «стандартный» способ сделать это - взять экземпляр базового класса в конструкторе вашего производного класса. Это пример шаблона декоратор

Со страницы википедии

В объектно-ориентированном программировании шаблон декоратор является шаблоном дизайна что позволяет новое / дополнительное поведение быть добавленным в существующий класс динамически.

3 голосов
/ 27 мая 2009

Некоторые возможные альтернативы:

  • Создайте класс-оболочку, не производя от ObjectOfAnUnchangeableClass, который не может быть получен из
  • Методы расширения

P.S .: о способах связывания и расширения данных, вы видели этот пост?
Как вызывать методы расширения с помощью Eval в элементе управления с привязкой к данным

3 голосов
/ 27 мая 2009

Я думаю Duck Typing потенциально может вам помочь. Это в основном позволит вам «приводить» между классами, которые не связаны с наследованием, но связаны с тем, как выглядят их поля. Похоже, они теперь используют динамический прокси-класс для перевода между типами. Я не совсем уверен, как это работает под прикрытием, но я собираюсь выяснить.

Синтаксис будет примерно таким:

MyDerivedClass Obj = 
     DuckTyping.Cast<MyDerivedClass>(ObjectOfAnUnchangeableClass);

По существу он скопирует все поля из ObjectOfAnUnchangeableClass в MyDerivedClass , которые имеют одинаковые имена Вы можете заархивировать то же поведение с помощью описанного вами метода, но если вам это не нравится, дайте этой библиотеке пройти.

2 голосов
/ 27 мая 2009

Вот третий вариант - создайте новый тип, который не расширяет UnchangeableClass, но содержит его экземпляр, который вы можете использовать, а затем предоставьте любые новые методы из этого нового типа:

class MyDerivedClass
{
    UnchangeableClass unchangeableClass;

    public MyDerivedClass(UnchangeableClass obj)
    {
        this.unchangeableClass = obj;
    }

    // other methods to support whatever you need
}

Я считаю, что это проще и чище, чем создание производного типа.

0 голосов
/ 27 мая 2009
  1. Возможно, преобразователь типа?
  2. Вы можете создать метод расширения - UnchangeableClass.ToMyDerivedClass ();
0 голосов
/ 27 мая 2009

Вызов конструктора вашего производного класса и передача исходного класса в качестве аргумента довольно проста. Если исходный класс уже имеет конструктор копирования, вам не нужно копировать свойства самостоятельно.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...