2015-02-08 2 views
0

У меня есть следующий интерфейс:Cast элемент списка для родового типа во время выполнения

interface IStorage 
{ } 

, а затем у меня есть класс, производный от этого интерфейса (который является общим), например, со свойством Get

public class ManagingModel<T> : IStorage 
{ 
    public Func<T> Get { get; set; } 
} 

чтобы получить список этих объектов, я использую List<IStorage>

вопрос заключается в том, как я бросил элемент из списка, чтобы ManagingModel<> открыть пропеллер erty?

+0

Вы должны указать имя собственности –

+0

Как вы знаете, какой тип вам нужно? Что такое код вызова, связанный с 'Func '? – Enigmativity

+0

@Enigmativity, пользователь моего кода создаст экземпляр 'ManagingModel ', и используя функцию 'Get', я получу некоторые объекты (это не имеет значения, с какой целью) –

ответ

2

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

var managingString = new ManagingModel<string>(); 
    var managingInt = new ManagingModel<int>(); 
    var managingDouble = new ManagingModel<double>(); 

    var list = new List<IStorage>(); 

    list.Add(managingString); 
    list.Add(managingInt); 
    list.Add(managingDouble); 

Попытка бросить «в» данной модели с помощью индекса:

var backToManagingModel = list[1] as ManagingModel<int>; 

    if (backToManagingModel != null) 
    { 
     var get = backToManagingModel.Get; 
    } 

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

Редактировать: Как же вообще не использовать дженерики, а просто использовать объект?

public static string GetString() 
    { 
     return "xyz"; 
    } 

    public interface IStorage 
    { 
     Func<object> Get { get; set; } 
    } 

    public class ManagingModel : IStorage 
    { 
     public Func<object> Get { get; set; } 
    } 

Вам не нужно будет проверять все типы, просто позвоните list[index].Get

 var managingString = new ManagingModel 
     { 
      Get = new Func<string>(GetString) 
     }; 

     var list = new List<IStorage>(); 

     list.Add(managingString); 

     var get = list[1].Get; 
+0

Спасибо за ответ, но может быть много типов (я не могу контролировать, какие они будут). Поэтому я не могу просто проверить все возможные варианты. –

+0

После обновления: да, я рассматривал этот подход, но я хотел бы использовать гибкость универсальных типов во время компиляции. –

1

Поскольку значение Func<T> будет вид, то вы, вероятно, может продлить IStorage сделать это как Func<object>.

Попробуйте это:

interface IStorage 
{ 
    Func<object> Get { get; } 
} 

public class ManagingModel<T> : IStorage 
{ 
    public Func<T> Get { get; set; } 

    Func<object> IStorage.Get 
    { 
     get 
     { 
      return() => this.Get(); 
     } 
    } 
} 
Смежные вопросы