2016-10-19 2 views
3

Я определил абстрактный класс с абстрактным ограничением:C# вентиляционных дженерик

abstract class Asset<P> where P : Parm { } 
abstract class Parm { } 

class StockParm : Parm { } 
class Stock : Asset<StockParm> { } 

class BondParm : Parm { } 
class Bond : Asset<BondParm> { } 

List<Asset<Parm>> assets = new List<Asset<Parm>>(); 
Stock stock; 
assets.Add(stock); 

Но я получил сообщение об ошибке:

«Невозможно преобразовать тип запас в актив»

Есть ли способ перечислить все assets?

Благодаря

+0

Возможный дубликат [Как правильно отдать свой класс абстрактный класс при использовании типовых генераторов?] (http: // sta ckoverflow.com/questions/25792563/how-to-correctly-cast-a-class-to-an-abstract-class-when-using-type-generics) – Tinwor

ответ

5

Вы должны объяснить компилятору, что Asset<Derived> является Asset<Base>. Компилятор компилирует общие классы в отсроченные классы - по одному для каждого T. Имя сообщения компилятору о том, что оно «нормально», равно covariant.

MSDN:

ковариации - Позволяет использовать более производный тип, чем первоначально указано. Вы можете присвоить экземпляр IEnumerable (IEnumerable (Of Derived) в Visual Basic) переменной типа IEnumerable.

Изменение Asset<T> к интерфейсу и добавьте out keyword:

interface Asset<out P> where P : Parm { } 

public static class Program 
{ 
    public static void Main(string[] args) 
    { 
     List<Asset<Parm>> assets = new List<Asset<Parm>>(); 
     Stock stock = new Stock(); 
     assets.Add(stock); 
    } 
} 

public abstract class Parm { } 
public class StockParm : Parm { } 

public interface Asset<out P> where P : Parm { }  
public class Stock : Asset<StockParm> { } 
+0

Согласен, что интерфейсы были бы полезны здесь. – Alex

+0

Ключевое слово 'out' означает ковариацию, а не контравариантность - ключевое слово' in'. – kiziu

+0

@kiziu - исправлена ​​моя ошибка + добавлена ​​как объяснение ключевого слова 'out'. Спасибо –

0

Пожалуйста, попробуйте следующее

List<Asset<StockParm>> assets = new List<Asset<StockParm>>(); 
+0

Нет, он хочет объявить список «Asset Params», а затем бросить в «Asset Param», это типичный случай «Contravariant» – Tinwor

+0

Это не дает ответа на вопрос , Чтобы критиковать или просить разъяснения у автора, оставьте комментарий ниже их сообщения. - [Из обзора] (/ review/low-quality-posts/14030415) – maazza

+0

@maazza Получил это. Благодаря!! –

Смежные вопросы