none
Como instancia uma List abstrata a parti de outras mais especificas RRS feed

  • Pergunta

  • Comunidade, me encontro com certa dificuldade e já vou agradecendo dês de já á quem puder dar sua opinião.

    Supondo que exista as classes  ClassA, ClassB, ClassC entre outras, e que todas implementem a interface AbstractClass

    segue meu problema.

    Em determinado momento do meu projeto preciso instanciar a seguinte lista : List<AbstractClass>

    a parti de qualquer lista de objetos que implemente a AbstractClass, por exemplo:

    List<ClassA>, List<ClassB>,List<ClasseC> ...

    //lista de objetos que implementem ClasseA, ClasseB, ClasseC

    public void meuMetodo(object objeto)
    {
    
    List<AbstractClass> listaAbstrata = (List<AbstractClass>)objeto
    
    }

    O codigo acima ilustra oque eu gostaria de fazer lembrando que o objeto passado como parâmetro pode ser  List<ClassA>, List<ClassB>,List<ClasseC> ...

    Contudo espero opiniões, mesmo se não souberem responder, aceito sugestões ate como o uso de outro numerador;


    • Editado Defoliveira sábado, 28 de dezembro de 2013 19:03
    sábado, 28 de dezembro de 2013 19:01

Todas as Respostas

  • Você poderia criar um método que espera um parâmetro de entrada genérico, assim que for chamar ele passar o tipo especifico pra não ficar Object e pra não precisar de conversão...

    public void meuMetodo<Tipo>(tipo objeto) where tipo : AbstractClass
    Ou tentar fazer assim...

    List<AbstractClass> generica = new List<ClassA>().ConvertAll(x => (AbstractClass)x);


    Leonardo Lourenço Silva


    sábado, 28 de dezembro de 2013 20:21
  • porém ai você declara dentro do método a lista como List<ClassA>() , eu não vou saber qual lista estou recebendo, pode ser List<ClassA>, List<ClassB>.

    Seria melhor eu usar um outro numerador que não precise declarar o tipo de objeto que esta listando

    domingo, 29 de dezembro de 2013 12:31
  • porém ai você declara dentro do método a lista como List<ClassA>() , eu não vou saber qual lista estou recebendo, pode ser List<ClassA>, List<ClassB>.

    Seria melhor eu usar um outro numerador que não precise declarar o tipo de objeto que esta listando

    Vamos lá !?

    é uma classe de Interface ou um Abstract Class ... o nome é do segundo mas, o que você relatou (implementar) é uma interface ... ??? tenho essa dúvida ???

    A real do seu código OK:

    public void meuMetodo(List<AbstractClass> ListaAbstrata)
    {
    	List<AbstractClass> listaAbstrata = ListaAbstrata;
    }

    Você postou o seu método e eu coloquei na norma ... !!! assim é o correto do seu código podendo passar qualquer das listas que implemente (que ainda tenho dúvida, apesar que não muda nada) a sua classe

    Exemplo de chamada

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace ConsoleAppEF.Code
    {
        public interface IGeral
        {
            int Code { get; set; }
            int Run();
        }
        public class GeralA : IGeral
        {
            public int Code { get; set; }
            public int Run()
            {
                return this.Code * 2;
            }
        }
        public class GeralB : IGeral
        {
            public int Code { get; set; }
            public int Run()
            {
                return this.Code * 6;
            }
        }
    }
    static void meuMetodo(List<IGeral> Geral)
    {
    	List<IGeral> _Geral = Geral;
    }
    
    static void Main(string[] args)
    {
    
    
    	List<IGeral> GeralA = new List<IGeral>();
    	GeralA.Add(new GeralA() { Code = 30 });
    	GeralA.Add(new GeralA() { Code = 15 });
    
    	List<IGeral> GeralB = new List<IGeral>();
    	GeralB.Add(new GeralB() { Code = 60 });
    	GeralB.Add(new GeralB() { Code = 75 });
    	
    	meuMetodo(GeralA);
    	meuMetodo(GeralB);
    }
    Não se eu entendi talvez esteja enganado, mas, vamos ver sua resposta?



    Fulvio Cezar Canducci Dias

    domingo, 29 de dezembro de 2013 13:28
  • Ou assim:

    Classes

    using System.Collections.Generic;
    using System.Linq;
    namespace ConsoleAppEF.Code
    {
        public interface IGeral
        {
            int Code { get; set; }
            int Run();
        }
    
        public class GeralA : IGeral
        {
            public int Code { get; set; }
    
            public int Run()
            {
                return this.Code * 2;
            }
        }
        public class GeralB : IGeral
        {
            public int Code { get; set; }
    
            public int Run()
            {
                return this.Code * 6;
            }
        }
    
        public class Geral : ICollection<IGeral>
        {
    
            private ICollection<IGeral> geral;
            public Geral()
            {
                geral = new List<IGeral>();
            }
            public void Add(IGeral item)
            {
                geral.Add(item);
            }
    
            public void Clear()
            {
                geral.Clear();
            }
    
            public bool Contains(IGeral item)
            {
                return geral.Contains(item);
            }
    
            public void CopyTo(IGeral[] array, int arrayIndex)
            {
                geral.CopyTo(array, arrayIndex);
            }
    
            public int Count
            {
                get { return geral.Count(); }
            }
    
            public bool IsReadOnly
            {
                get { return false; }
            }
    
            public bool Remove(IGeral item)
            {
                return geral.Remove(item);
            }
    
            public IEnumerator<IGeral> GetEnumerator()
            {
                return geral.GetEnumerator();
            } 
            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                return geral.GetEnumerator();
            }
        }
    }
    

    Como Usar:

    static void meuMetodo(ICollection<IGeral> Geral)
    {
    	ICollection<IGeral> _Geral = Geral;
    }
    static void Main(string[] args)
    {
    	ICollection<IGeral> Geral = new Geral();
    	Geral.Add(new GeralA());
    	Geral.Add(new GeralB());
    
    	meuMetodo(Geral);
    }

    Não se tira sua dúvida mais ai pergunte se não for a solução?


    Fulvio Cezar Canducci Dias

    domingo, 29 de dezembro de 2013 13:42
  • porém ai você declara dentro do método a lista como List<ClassA>() , eu não vou saber qual lista estou recebendo, pode ser List<ClassA>, List<ClassB>.

    Seria melhor eu usar um outro numerador que não precise declarar o tipo de objeto que esta listando

    Teoricamente é só fazer o looping e dar um GetType pra pegar a tipagem, mas são 2 possíveis soluções...

    Uma terceira solução também, é alterar de List pra IEnumerable pra ficar variante e fazer o GetType...


    Leonardo Lourenço Silva


    domingo, 29 de dezembro de 2013 15:09
  • Este seria um exemplo mais preciso do que quero fazer 

    //pego as propriedades de um objeto
    PropertyInfo[] propriedades =Objeto.getType().getPropreties();
    
    foreach(PropertyInfo propriedade in propriedades)
    {
    //se a propriedade for uma lista
    //nao sei de que é a lista mas sei que qualquer elemento //da lista vai implementar InterfaceA
    List<InterfaceA> lista = propriedade.getValue(Objeto);
    
    //aqui realizo minha logica com os elementos da lista
    }


    segunda-feira, 30 de dezembro de 2013 00:23
  • Este seria um exemplo mais preciso do que quero fazer 

    //pego as propriedades de um objeto
    PropertyInfo[] propriedades =Objeto.getType().getPropreties();
    
    foreach(PropertyInfo propriedade in propriedades)
    {
    //se a propriedade for uma lista
    //nao sei de que é a lista mas sei que qualquer elemento //da lista vai implementar InterfaceA
    List<InterfaceA> lista = propriedade.getValue(Objeto);
    
    //aqui realizo minha logica com os elementos da lista
    }


    Isso vai depender muito da confecção da sua classe!

    Seria muito mais tranquilo você passar suas classes e mostrar um exemplo igual eu mesmo postei!

    Esses são algumas das formas de extrair dados contindos em um objeto de uma classe!

    Type Tipo = Geral.GetType();
    PropertyInfo[] Propriedades = Tipo.GetProperties();
    MethodInfo[] Metodos = Tipo.GetMethods();
    MemberInfo[] Membros = Tipo.GetMembers();
    FieldInfo[] Campos = Tipo.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

    O meu exemplo, seguindo a lógica para pegar cada item da Coleção seria na variavel FiledInfo (Campos), porque, nesse exemplo resgato a coleção de um campo não publico da minha classe de coleção e com ela consigo varrer e fazer o seu exemplo logo acima, trazendo os dois dados contidos nessa lista

    ICollection<IGeral> Geral = new Geral();
    Geral.Add(new GeralA());
    Geral.Add(new GeralB());
    
    
    Type Tipo = Geral.GetType();
    PropertyInfo[] Propriedades = Tipo.GetProperties();
    MethodInfo[] Metodos = Tipo.GetMethods();
    MemberInfo[] Membros = Tipo.GetMembers();
    FieldInfo[] Campos = Tipo.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
    foreach (FieldInfo item in Campos)
    {
    	ICollection<IGeral> iTipo = (ICollection<IGeral>)item.GetValue(Geral);                
    }

    Imagem:


    Fulvio Cezar Canducci Dias

    segunda-feira, 30 de dezembro de 2013 12:27
  • Obrigado  Fúlvio Cezar Canducci Dias, ajudou bastante, mas mesmo se Classe implementar Interface  ICollection<Classe> pode ser transformado via (Cast) em um  ICollection<Interface> ?
    quarta-feira, 1 de janeiro de 2014 14:43
  • Eu não entendi muito bem, se poderia supor em código isso?

    Você só pode instânciar classe Concreta, as interfaces servem como modelo para outras classes!!! Então se um classe implementa a interface você pode tipar com essa interface e instância pela classe concreta

    Exemplo:

    public interface IPessoas
    {
    	int Id { get; set; }
    	string Nome { get; set; }
    	DateTime DataAniversario { get; set; }
    	decimal Valor { get; set; }
    }
    public class Pessoas: IPessoas
    {
    	public Pessoas() { }
    	public Pessoas(IPessoas pessoa)
    	{
    		Id = pessoa.Id;
    		Nome = pessoa.Nome;
    		Valor = pessoa.Valor;
    		DataAniversario = pessoa.DataAniversario;
    	}
    	public int Id { get; set; }
    	public string Nome { get; set; }
    	public DateTime DataAniversario { get; set; }
    	public decimal Valor { get; set; }
    }

    Exemplo de utilização:

    IPessoas p1 = new Pessoas();
    IPessoas P2 = new Pessoas(p1);

    Isso é tudo exemplos mas, é claro que deve atentar o contexto de sua aplicação, mas, são formas viáveis de se fazer  ...

    Se ainda não atendeu por favor relate esse Cast porque o Cast nesse caso não to vendo necessidade:

    será que você ta dizendo isso:

    IPessoas p1 = (IPessoas)(new Pessoas());
    Se for não precisa!!!


    Fulvio Cezar Canducci Dias

    quarta-feira, 1 de janeiro de 2014 18:38
  • //interface

    public interface Interface1{}


    //classe

    public class Classe1 : Interface1{}


    //interface que possuirá a lista


    public interface InterfaceTeste
    {
    public ICollection<Interface1> GetLista();



    //classe que implementará a interface teste

    public class ClasseTeste

    {

    private ICollection<Classe1> _listaObjetos // ou lList

    public ClasseTeste(){

    _listaObjetos = new ICollection<Classe1>();

    _listaObjetos.Add(new Classe1());

    _listaObjetos.Add(new Classe2());

    }// inserir um valor qualquer na  ICollection ou List , para não haver NullException

    public ICollection<Interface1> GetLista()
    {
    return _listasObjetos;

    }


    }



    public classe Program()

    {

    public static void Main(string[] args)

    {

    InterfaceTeste c = InterfaceTesteFactory.getInterfaceTeste(1);

    ICollection<Interface1> lista = c.GetLista();// quero saber se isto pode dar certo !!!!!!

    //codigo qualquer usando a lista

    Interface1 obj = lista.First();

    Type type = obj.getType();

    //fim

    }

    }


    bom este e o exemplo de que quero fazer , fiz correndo só para demonstrar , então peço que desconsidere erros que desviem o foco do que realmente procuro saber


    • Editado Defoliveira quarta-feira, 1 de janeiro de 2014 21:53
    quarta-feira, 1 de janeiro de 2014 21:49
  • Do jeito que você fez não !!!

    Assim seria a normativa do seu código, não vou falar nem em padrão nem nada somente funcional OK!

    Assim:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleAppDbEF
    {
        public interface Interface1 { }
        public class Classe1 : Interface1 { }
        public class Classe2 : Interface1 { }
    
        public interface InterfaceTeste
        {
            ICollection<Interface1> GetLista();
        } 
        public class ClasseTeste: InterfaceTeste 
        {
    
            private ICollection<Interface1> _listaObjetos;
            public ClasseTeste(){
    
                _listaObjetos = new List<Interface1>();
    
                _listaObjetos.Add(new Classe1());
    
                _listaObjetos.Add(new Classe2());
            }   
    
            public ICollection<Interface1> GetLista()
            {
                return _listaObjetos;
            }
        }
    }

    static void Main(string[] args)
    {
    	InterfaceTeste c = new ClasseTeste();
    	ICollection<Interface1> l =  c.GetLista();
    	Interface1 in1 = l.First();
    	Type tip = in1.GetType();
    }


    Fulvio Cezar Canducci Dias

    quarta-feira, 1 de janeiro de 2014 23:22