Problem accessing concrete class methods using reference this in C#

Asked

Viewed 52 times

-1

I implemented a class Service abstract using Generics and another using EmpresaService being concrete.

Every project structure for every concrete class has an abstract.

My doubt seeing from the following...

When using the reference this.Dao.ExisteRegistro();, it points to the method in the abstract class and not in the concrete class, and this is bad because it complicates when implementing individual methods in the class EmpresaDao for example.

My mistake is being in the class project?

Planoservice class

using System;
using System.Collections.Generic;
using Cobranca.pkgDao;
using Cobranca.pkgModel;

namespace Cobranca.pkgService
{
    public class PlanoService : Service<Plano>
    {

        public PlanoService()
        {
            this.Dao = new PlanoDao();
        }

        //método em questão que mostra o erro
        public bool ExisteRegistro()
        {
            return this.Dao.ExisteRegistro();
        }

        // métodos e mais métodos abaixo
    }
}

Class Empresadao

using System;
using System.Collections.Generic;
using Cobranca.pkgModel;
using MySql.Data.MySqlClient;

namespace Cobranca.pkgDao
{
    class EmpresaDao : Dao<Empresa>
    {
        public bool ExistePlanos()
        {
            try
            {
                base.AbrirConexao();
                MySqlCommand cmd = base.Conexao.CreateCommand();
                cmd.CommandText = "SELECT COUNT(*) FROM planos";
                return Convert.ToInt32(cmd.ExecuteScalar()) > 0;
            }
            finally
            {
                base.FecharConexao();
            }
        }
    }
}

Classe Dao

using System;
using MySql.Data.MySqlClient;
using Cobranca.pkgModel;
using System.Collections.Generic;

namespace Cobranca.pkgDao
{

    public abstract class Dao<TModel> where TModel : Persistant
    {
        public abstract bool Inserir(TModel model);
        public abstract bool Editar(TModel model);
        public abstract bool Excluir(long codigo);

        public abstract List<TModel> CarregarDados();

    }
}


Classe PlanoDao

using System;
using System.Collections.Generic;
using MySql.Data.MySqlClient;
using Cobranca.pkgModel;

namespace Cobranca.pkgDao
{
    public class PlanoDao : Dao<Plano>
    {
        public bool ExisteRegistro()
        {
            try
            {
                base.AbrirConexao();
                MySqlCommand cmd = base.Conexao.CreateCommand();
                cmd.CommandText = "SELECT COUNT(*) FROM planos";
                return Convert.ToInt32(cmd.ExecuteScalar()) == 1;
            }
            finally
            {
                base.FecharConexao();
            }
        }
    }
}
  • 1

    You could add the complete codes, because your examples are in the informed codes. The method this.Dao.ExisteRegistro(); is calling for PlanoDao and not EmpresaDao. Already EmpresaDao doesn’t have the méotod ExisteRegistro.

  • I didn’t add the entire class to avoid polluting the code, but I added part of the class PlanoDao;

1 answer

2


"When using the reference this.Dao.Existeregistro();, it points to the method in the abstract class"

The reserved word this always references the current class, to reference the class to which it is extending, is used base.

From the MSDN documentation:

The keyword this refers to the current instance of the class and is also used as a modifier of the first parameter of a extension.

Reference: https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/keywords/this

To demonstrate this, I made a small block of code:

public abstract class ClasseAbstrata
{
    public abstract bool Inserir(int x);
    public abstract bool Editar(int x);
    public abstract bool Excluir(int x);

    public string QuemSouEu()
    {
        return "Abstrata";
    }
}

public class Derivada : ClasseAbstrata
{
    public override bool  Inserir(int x) { return false; }
    public override bool Editar(int x) { return false; }
    public override bool Excluir(int x) { return false; }

    public string QuemSouEu()
    {
        return "Derivada";
    }

    public string QuemSouEuBase()
    {
        return base.QuemSouEu();
    }
    public string QuemSouEuThis()
    {
        return this.QuemSouEu();
    }
    public string QuemSouEuParseAbstrata()
    {
        return ((ClasseAbstrata)this).QuemSouEu();
    }
    public string QuemSouEuParseDerivada()
    {
        return ((Derivada)this).QuemSouEu();
    }
}

I took the example of the class above, and added a method in the abstract class: QuemSouEu(). As the other methods are abstract and not implementation in the class abastrata, this will have no practical effect here, so let’s see how the method behaves QuemSouEu using that code:

var d = new Derivada();
Console.WriteLine("QuemSouEu: " + d.QuemSouEu());
Console.WriteLine("QuemSouEuBase: " + d.QuemSouEuBase());
Console.WriteLine("QuemSouEuThis: " + d.QuemSouEuThis());
Console.WriteLine("QuemSouEuParseAbstrata: " + d.QuemSouEuParseAbstrata());
Console.WriteLine("QuemSouEuParseDerivada: " + d.QuemSouEuParseDerivada());

Results:

Quemsoueu: Derivative
Whosoueubase: Abstract
Quemsoueuthis: Derivative
Quemsoueuparseabstractabstract: Abstract
Whosoueuparsederivative: Derivative

We can notice that where it was used this (Quemsoueuthis) returned from the derived class, not the abstract, even overwriting the method.

Other comments:
- base references the abstract class;
- it is possible to do cast for any of the classes to have the expected result (Quemsoueuparseabstracte and Quemsoueuparsederivative methods)

Here the fiddle: https://dotnetfiddle.net/mc7u2E

Browser other questions tagged

You are not signed in. Login or sign up in order to post.