LINUX.ORG.RU

[C#] Приведение типов при наследовании


0

1

Здравствуйте, уважаемые форумчане и форумчанки. У меня к вам следующий вопрос: есть к примеру, такой код

Foo foo = new Bar()
, где Foo класс-предок, а Bar - наследник. Как при этом в C# преобразовать исходный тип Foo сразу же к типу Bar?

Явных указаний на эту тему я в Гугле и учебниках пока не нашел, хотя допускаю, что мог просто плохо читать. Нашел только, что в такой ситуации будет автоматом выполнено преобразование типа Bar -> Foo, но мне нужно наоборот. Извините за сумбурное изложение, вечер уже все-таки.

Заранее благодарен за ваши ответы.

приведи типы, коли надо. ((Bar)foo).BarMethod(); так это будет выглядеть. иль сделай ещё одну ссылку на объект Bar bar=(Bar)foo;

//на шарпах не пишу

RedPossum ★★★★★
()
Ответ на: комментарий от RedPossum

Работает такой вариант, но правда код убого смотрится. А нельзя ли сразу при создании объекта такой фокус провернуть, чтоб каждый раз такого не писать?

LongLiveUbuntu ★★★★★
() автор топика
Ответ на: комментарий от dizza

Печально. В Java очень удобно этот вопрос решен. Т.е. там можно написать что-то типа

Map myMap = new HashMap()
и переменная myMap будет иметь фактически тип HashMap.

LongLiveUbuntu ★★★★★
() автор топика
Ответ на: комментарий от uGin

Гм... Ну, в общем-то Map - это интерфейс, который реализуют классы TreeMap, HashMap и SortedMap соответственно. Но тем не менее... Возможно чего-то не понял я, не буду отрицать. Если кто знает, как правильно, подскажите. Только от темы как с Обероном отклоняться не надо :)

LongLiveUbuntu ★★★★★
() автор топика

Не понятно, что ты хочешь. В C# это работает абсолютно идентично джаве. Никаких отличий.

Legioner ★★★★★
()
Ответ на: комментарий от LongLiveUbuntu

и в с# у тебя ссылочный тип ссылается на реальный объект. только вот вызвать специфичные для объекта методы, свойства и проч. и проч. тебе не дают. в яве разве не так же?

RedPossum ★★★★★
()
Ответ на: комментарий от RedPossum

Нет. Там если ссылается на объект, то свойства и методы этого объекта и будут доступны. То есть, если я сделаю вместо Map myMap = new HashMap() - Map myMap = new TreeMap(), то в дальнейшем я буду работать с myMap как с TreeMap.

LongLiveUbuntu ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

Да можно же, но мне удобней было бы как Foo foo = new Bar().

LongLiveUbuntu ★★★★★
() автор топика

Foo foo = new Bar();

В данном случае произойдет восходящее преобразование к базовому типу, но во время выполнения, сработает механизм RTTI, который определит точный тип объекта и вызовет соответствующий метод производного класса.

virus
()

ТС ты жутко тупишь, иди читай про полиморфизм. Это даже не основы, это в детском саду изучают наряду с арифметикой и чтением.

anonymous
()
Ответ на: комментарий от LongLiveUbuntu

сдаётся мне, путаешь ты абстрактные классы и обычные.

RedPossum ★★★★★
()
Ответ на: комментарий от LongLiveUbuntu

> Map - это интерфейс, который реализуют классы TreeMap, HashMap и SortedMap соответственно.

Тут интерфейс, там классы. Вроде всё понятно.

tensai_cirno ★★★★★
()

Вообще-то так делают прыщавые соски, не достигшие половой зрелости проффессиянала.

А теперь по каждому дефекту подробнее.

1. Почему объявляешь Foo, а не Bar, раз использовать собрался Bar ?
2. Предположим, Foo используешь из соображений обобщения. Так какого хрена не построил нормальную иерархию, раз приперло кастовать?

Как ни крути, а пока что твой вопрос лишь указывает на твой общий уровень (низкий, естессно).

yaws
()
Ответ на: комментарий от LongLiveUbuntu

Да нет же. Будут доступны только то, что есть в интерфейсе Map. А вызываться будут методы того объекта, на который указывает эта ссылка. Я уверен, что в C# это так же, потому что это так же даже в C++, ибо так должно быть :-) Правильно сказали - почитай про полиморфизм. Ну и объявляй переменную сразу нужного типа, в сторону родителя всегда можно безопасно закастить.

P.S. долго вчитывался в топик и комментарии, так и не понял, то ли у меня НГ уже наступил, то ли у ТС.

roy ★★★★★
()
Ответ на: комментарий от FollowTheRabbit

Я не употребляю вещества. И не знаком с filosof'ом :)

LongLiveUbuntu ★★★★★
() автор топика
Ответ на: комментарий от yaws

1. Раньше в Java делал так всегда. Прокатывало. Видимо, в С# свои тонкости, буду копать еще.

2. Эта иерархия уже построена в Gtk# до меня.

3. Насчет уровня не отрицаю, опыта маловато пока что. Толковых бы наставников мне (

LongLiveUbuntu ★★★★★
() автор топика

C#+Тупняк=Унылый троллинг

Можно было бы придумать что-нибудь по оригинальнее. Лучше бы выбрал Lisp+Тупняк, ИМХО веселее.

pathfinder ★★★★
()
Ответ на: комментарий от FollowTheRabbit

Еще раз - это не троллинг. Это реальное затруднение для меня. Хотя из вышепредложенных вариантов я остановился на (foo as Bar).methodBar(), как на работающем. Юзеру RedPossum большое спасибо за моральную и интеллектуальную поддержку. Всем остальным тоже.

LongLiveUbuntu ★★★★★
() автор топика
Ответ на: комментарий от LongLiveUbuntu

А чем тебе не нравится?

Bar bar = (Bar)foo;
bar.SomeMethod();

Ты все равно проверку на приведение типа не делаешь, так хоть текст исключения будет более осмысленным в случае неправильного приведения.

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

То есть мне еще одну переменную заводить? Для чего?

Проще тогда сразу же

Bar bar = new Bar()

LongLiveUbuntu ★★★★★
() автор топика

Прочитал всю ветку, так и не понял, какой Java-код топикстартеру не удаётся переписать на шарпе.

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

Фишка не в Java - коде. А в том, возможно ли в шарпе неявно привести тип класса-предка к типу класса-потомка? То есть использовать его свойства и методы.

LongLiveUbuntu ★★★★★
() автор топика
Ответ на: комментарий от LongLiveUbuntu

Фишка не в Java - коде. А в том, возможно ли в шарпе неявно привести тип класса-предка к типу класса-потомка?

Фишка - в коде. Ибо прежде чем выяснять, возможно ли в шарпе ..., нужно показать, как оно может выглядеть хоть где-нибудь, а то непонятно нифига, чего хочется.

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

В Java очень удобно этот вопрос решен. Т.е. там можно написать что-то типа

Map myMap = new HashMap()

и переменная myMap будет иметь фактически тип HashMap.

Вот образец.

LongLiveUbuntu ★★★★★
() автор топика
Ответ на: комментарий от LongLiveUbuntu

и переменная myMap будет иметь фактически тип HashMap.

Блин-тарарам.

ЧТО ЗНАЧИТ «ФАКТИЧЕСКИ»?????? КАК ЭТО ВЫРАЖАЕТСЯ В КОДЕ?????

Miguel ★★★★★
()
Ответ на: комментарий от LongLiveUbuntu

> привести тип класса-предка к типу класса-потомка. То есть использовать его свойства и методы.

это полный абзац. Читаем базовые принципы ООП до посинения

FollowTheRabbit
()
Ответ на: комментарий от Miguel

Это выражается в том, что в последствии я могу написать после этого вызова конструктора так: [code=java] myMap.addKey(key); myMap.addValue(value);[/code] (пишу по памяти). Т.е. фактически обращаться к методам и свойствам, специфичным для класса HashMap. Обратно, если я вызову сначала конструктор для TreeMap, то я буду работать уже с его полями и методами в переменной myMap.

LongLiveUbuntu ★★★★★
() автор топика
Ответ на: комментарий от LongLiveUbuntu
import java.util.HashMap;
import java.util.Map;
public class Test {
    public void test() {
	Map myMap = new HashMap();
	myMap.addKey(1);
    }
}
MigMit:~ MigMit$ javac Test.java
Test.java:6: cannot find symbol
symbol  : method addKey(int)
location: interface java.util.Map
	myMap.addKey(1);
	     ^
1 error

Поздравляю вас, гражданин, соврамши.

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

Я ж говорю, привожу код по памяти, мог в деталях и ошибиться. Но оно примерно так там и работало. Хорстманна и Корнелла найдите «Java 2». Том второй, глава «Коллекции.Карты», к примеру.

LongLiveUbuntu ★★★★★
() автор топика
Ответ на: комментарий от LongLiveUbuntu

Блин-тарарам ещё раз.

Я который раз прошу привести РАБОЧИЙ код, иллюстрирующий вашу идею.

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

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

Поздравляю вас, гражданин, соврамши.

Если ты не знаешь Java, это твои проблемы.

import java.util.HashMap;
import java.util.Map;


public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Map myMap = new HashMap();
		myMap.put(1, 2);
	}

}

Все работает.

stave ★★★★★
()
Ответ на: комментарий от stave

Если ты не знаешь Java, это твои проблемы.

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

Все работает.

Естественно. put - метод интерфейса Map, для класса HasрMap он специфичным не является.

Miguel ★★★★★
()
Ответ на: комментарий от LongLiveUbuntu
 Т.е. фактически обращаться к методам и свойствам, специфичным для класса HashMap. Обратно, если я вызову сначала конструктор для TreeMap, то я буду работать уже с его полями и методами в переменной myMap. 

Как-то неправдоподобно выглядит, и при передачи в функцию тоже работает?

Booster ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.