none
Como fazer um método de uma classe base, retornar um objeto do tipo da classe herdada???

    Question

  • Boa tarde!!!

     

    Gostaria de saber se é possível criar um método em uma classe base que retorne um objeto do tipo da classe herdada, já que a classe base agora é a classe herdada???

     

    Quero retornar um objeto do tipo gereric da classe herdada, do tipo List<ClasseHerdada>, mas feito isso na classe base!

     

       Aqui posto o meu exemplo de código retornando um Objeto do tipo object!!! Porem eu quero retornar um objeto do tipo da classe herdada!!!

     

    /// <summary>

    /// Lista dados das propridades da classe que herdou da nossa classe base.

    /// </summary>

    /// <returns>Retorna objeto atual.</returns>

    public List<object> ListarTudo()

    {

    if (DataBaseIsConfigured())

    {

    string _select = "Select {0} from {1}";

    List<object> retBOPersist = new List<object>();

    dbFactory = DbProviderFactories.GetFactory(DataBaseConfigure.ProviderName);

    dbConnection = dbFactory.CreateConnection();

    dbConnection.ConnectionString = DataBaseConfigure.ConnectionString;

    dbCommand = dbFactory.CreateCommand();

    dbCommand.CommandText = string.Format(_select, getColumnsList(), getTableName());

    dbCommand.Connection = dbConnection;

    try

    {

    dbConnection.Open();

    DbDataReader dbReader = null;

    dbReader = dbCommand.ExecuteReader(CommandBehavior.CloseConnection);

    if (dbReader.HasRows)

    {

    //Enquanto existir dados para serem lidos.

    //Lemos registro por registro retornado do banco de dados.

    while (dbReader.Read())

    {

    object boRecord = this;

    //Temos de ler campo por campo da classe atual para pegar os campos de banco de dados

    //e passar os mesmos para o dbReader e pegar o valor do dbReader e passar os valores

    //para as propriedades do objeto.

    //Então fazemos uma verredura no objeto boRecord e jogamos as suas propriedades

    //dentro de um objeto do tipo PropertyInfo.

    foreach (PropertyInfo prop in boRecord.GetType().GetProperties())

    {

    string _valor;

    //Criamos um objeto para conversão dos tipos de dados,

    //a propriedade do objeto PropertyInfo "PropertyType" retorna o tipo de dado da propriedade.

    TypeConverter conv = TypeDescriptor.GetConverter(prop.PropertyType);

    //Criamos um array de objetos, selecionando apenas as propriedades

    //que estão marcadas com o atributo do tipo ColumnAttribute.

    object[] cols = prop.GetCustomAttributes(typeof(ColumnAttribute), true);

    //Criamos outro array com propriedades marcadas com atributo do tipo KeyAttribute.

    object[] keys = prop.GetCustomAttributes(typeof(KeyAttribute), true);

    //Se ambos objetos estiverem cheios, o nome do campo é o mesmo.

    //Pegamos o nome somente de um dos objetos, evitando a duplicidade de campos.

    if (cols.Length == 1 && keys.Length == 1)

    {

    //Para que possamos chamar nosso atributos pelo nome

    //devemos criar um objeto do seu tipo, ColumnAttribute

    //e dizer ao objeto cols[0] que ele será do tipo ColumnAttribute.

    ColumnAttribute ca = cols[0] as ColumnAttribute;

    _valor = dbReader[ca.ColumnName].ToString();

    prop.SetValue(boRecord, conv.ConvertFrom(_valor), null);

    }

    else if (cols.Length == 1 && keys.Length == 0)

    {

    ColumnAttribute ca = cols[0] as ColumnAttribute;

    _valor = dbReader[ca.ColumnName].ToString();

    prop.SetValue(boRecord, conv.ConvertFrom(_valor), null);

    }

    else if (cols.Length == 0 && keys.Length == 1)

    {

    KeyAttribute key = keys[0] as KeyAttribute;

    _valor = dbReader[key.KeyName].ToString();

    prop.SetValue(boRecord, conv.ConvertFrom(_valor), null);

    }

    }

    retBOPersist.Add(boRecord);

    }

    dbReader.Close();

    }

    }

    /*catch (Exception ex)

    {

    throw new Exception("Ocorreu ume exceção durante a execução do método ListarTudo()!", ex);

    }*/

    finally

    {

    dbConnection.Close();

    }

    return retBOPersist;

    }

    else

    return null;

    }

    #endregion

    Thursday, March 29, 2007 4:42 PM

Answers

  • Voce não pode fazer o cast de List<ClasseBase> para List<ClasseHerdada>. Não há relação. O objeto List é só uma coleção genérica.

     

    Você deve fazer com que *todos* os métodos recebam uma List do tipo ClasseBase, que é o tipo comum do qual todas as classes derivarão, e depois você simplesmente faz o cast dos objtos individuais contidos no List:

     

    public class ClasseBase
    {
        public string m_valor = string.Empty;
     
        public List<ClasseBase> UmMetodo()
        {
            ClasseHerdada ch1 = new ClasseHerdada();
            ch1.m_valor = "Olá da classe base 1";
            ch1.m_valorHerdada = "Blahblahblah 1";
     
            ClasseHerdada ch2 = new ClasseHerdada();
            ch2.m_valor = "Olá da classe base 2";
            ch2.m_valorHerdada = "Blahblahblah 2";
     
            List<ClasseBase> lista = new List<ClasseBase>();
     
            lista.Add((ClasseBase)ch1);
            lista.Add((ClasseBase)ch2);
     
            return lista;
        }
    }
     
    public class ClasseHerdada : ClasseBase
    {
        public string m_valorHerdada;
    }

     

    Uso:

     

    ClasseHerdada objHerd = new ClasseHerdada();
     
    List<ClasseBase> objList = new List<ClasseBase>();
     
    objList = objHerd.UmMetodo();
     
    foreach (ClasseBase cb in objList)
    {
        ClasseHerdada ch = (ClasseHerdada)cb;
     
        Console.WriteLine(ch.m_valor);
        Console.WriteLine(ch.m_valorHerdada);
    }

     

     

    Thursday, March 29, 2007 11:03 PM

All replies

  • É isso?

     

    public class ClasseBase
    {
        public string m_valor = string.Empty;
     
        public ClasseHerdada UmMetodo()
        {
            ClasseHerdada ch = new ClasseHerdada();
            ch.m_valor = "Olá da classe base";
            return ch;
        }
     
    }
     
    public class ClasseHerdada : ClasseBase
    {
     
    }

     

    Uso:

     

    ClasseBase cb = new ClasseBase();
     
    Console.WriteLine(cb.UmMetodo().m_valor);

     

    Thursday, March 29, 2007 5:07 PM
  • Infelismente não!!!!

     

    Esse método que deve ser implementado na classe base e que retornará um objeto do tipo da classe herdada, deve poder retornar vários tipos de classes diferentes! Qualquer uma que herdar da classe base, eu não posso me prender a um tipo!

     

    Veja que á classe base, por sua vez consegue manipular dados da classe herdada através de REFLECTION, já que a classe base passa a ser propriamente dito a classe herdada.

     

    Porem agora falta eu retornar uma lista do tipo da classe herdada.

     

    O que eu preciso, é retornar uma Lista do tipo da classe herdada???

    Thursday, March 29, 2007 7:03 PM
  • Mas se a classe é derivada, você pode fazer isso. Veja:

     

    public class ClasseBase
    {
        public string m_valor = string.Empty;
     
        public ClasseBase UmMetodo()
        {
            ClasseHerdada ch = new ClasseHerdada();
            ch.m_valor = "Olá da classe base";
            ch.m_valorHerdada = "Blahblahblah";
            return (ClasseBase)ch;
        }
    }
     
    public class ClasseHerdada : ClasseBase
    {
        public string m_valorHerdada;
    }

     

    Uso:

     

    ClasseBase cb = new ClasseBase();
     
    ClasseHerdada ch = (ClasseHerdada)cb.UmMetodo();
     
    Console.WriteLine(ch.m_valor);
    Console.WriteLine(ch.m_valorHerdada);

     

     

     

    Thursday, March 29, 2007 7:59 PM
  • Estamos quase lá!!!!

     

    Muito obrigado por responder as minhas perguntas....

     

    Neste caso eu gostaria de definir o método que você criou da seguinte forma:

     

    public class ClasseBase
    {
        public string m_valor = string.Empty;
     
        public List<ClasseBase> UmMetodo()
        {
            Retorna lista do tipo ClasseBase.
        }
    }
     
    public class ClasseHerdada : ClasseBase
    {
       //Propriedades diversas...
    }
     
    public class OutraClasse
    { 

    ClasseHerdada objHerd = new ClasseHerdada();

    List<ClasseHerdada> objList = new List<ClasseHerdada>(); o

    objList = objHerd.UmMetodo();

    }

     
    UmMetodo provem da classe base da classe herdada, utilizo-o aqui e tento passar os seus valores para um
    objeto list do tipo da classe herdada.
     
    o método UmMetodo é do tipo List<ClasseBase> já o objeto que vai recebelo é do tipo List<ClasseHerdada>
    ao passar o método List<ClasseBase> para o objeto do tipo List<ClasseHerdada> obtenho um erro???
     
    Acho que é só isso o meu problema devo ter complicado um pouco no início....
     
    Sabes como fazer a conversão???
    ou como retornar um objeto do tipo ClasseHerdada de dentro da classe base, mas sem utilizar a classe herdada
    na classe base.
     
    Se eu utilizasse ClasseHerdada3 que herda da ClasseBase o método deveria de retornar 
    um objeto do tipo ClasseHerdada3... Bom mas acho que é só retornar classebase mesmo, pois todas elas herdam 
    de classebase. Mas como fazer a conversão com o objeto do tipo List<>???
     
    Ou qualquer uma das outras perguntas....
     
    Agradeço muito a sua ajuda!
    Obrigado.
     
     
    Thursday, March 29, 2007 9:04 PM
  • Voce não pode fazer o cast de List<ClasseBase> para List<ClasseHerdada>. Não há relação. O objeto List é só uma coleção genérica.

     

    Você deve fazer com que *todos* os métodos recebam uma List do tipo ClasseBase, que é o tipo comum do qual todas as classes derivarão, e depois você simplesmente faz o cast dos objtos individuais contidos no List:

     

    public class ClasseBase
    {
        public string m_valor = string.Empty;
     
        public List<ClasseBase> UmMetodo()
        {
            ClasseHerdada ch1 = new ClasseHerdada();
            ch1.m_valor = "Olá da classe base 1";
            ch1.m_valorHerdada = "Blahblahblah 1";
     
            ClasseHerdada ch2 = new ClasseHerdada();
            ch2.m_valor = "Olá da classe base 2";
            ch2.m_valorHerdada = "Blahblahblah 2";
     
            List<ClasseBase> lista = new List<ClasseBase>();
     
            lista.Add((ClasseBase)ch1);
            lista.Add((ClasseBase)ch2);
     
            return lista;
        }
    }
     
    public class ClasseHerdada : ClasseBase
    {
        public string m_valorHerdada;
    }

     

    Uso:

     

    ClasseHerdada objHerd = new ClasseHerdada();
     
    List<ClasseBase> objList = new List<ClasseBase>();
     
    objList = objHerd.UmMetodo();
     
    foreach (ClasseBase cb in objList)
    {
        ClasseHerdada ch = (ClasseHerdada)cb;
     
        Console.WriteLine(ch.m_valor);
        Console.WriteLine(ch.m_valorHerdada);
    }

     

     

    Thursday, March 29, 2007 11:03 PM