Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

C# - Fazer uma classe ser instanciada apenas por uma outra classe

Eu tenho uma classe pública chamada ContaCorrente e uma outra classe chamada Banco. A classe Banco tem uma função que cria uma ContaCorrente e retorna ela (public BankAccount CreateBankAccount(...)).

Toda vez que uma conta é criada com sucesso ela incrementa uma uma variável static dentro de Banco. Acontece que é possível instanciar uma ContaCorrente sem a classe banco. Com isso o contador não é atualizado. Já tentei deixar a classe ContaCorrente Interna mas aí da problema de compilação no Banco pq a função CreateBankAccount é publica e dá problema de acessibilidade.

No c++ eu conseguia usar ponteiros pra resolver esse problema (deixava a função void e o ponteiro inicializava essa variável que ficava fora da função e era passada como argumento). Eu sei que poderia deixar o construtor de ContaCorrente interno e criar um construtor vazio que dispara um Exception (assim obrigo ele a usar a Classe Banco), mas gostaria de ter uma outra solução.

7 respostas

Você poderia usar If ao invés de Exception para ele usar a Classe Banco. Mas é difícil de dizer sem olhar o código, teria como postar ele aqui por gentileza?

public class Bank {

    static public int TotalBankAccounts { get; private set; }


    public BankAccount CreateBankAccount(string BankOwnerName, string BankOwnerCPF, bool bInIsWoman, int InBankID, int InBankAccountID, double InitialBalance)
    {
        BankAccount NewBankAccount;

        NewBankAccount = new BankAccount(BankOwnerName, BankOwnerCPF, bInIsWoman ,  InBankID, InBankAccountID, InitialBalance);


        if(NewBankAccount == null)
        {
            Console.WriteLine("Unfortunately this account could not be created!");
            return null;
        }
        else
        {
            string Title = NewBankAccount.Client.bIsWoman ? "Miss " : "Mrs.";

            Console.WriteLine("Account created! Hello " + Title + NewBankAccount.Client.Name);

            TotalBankAccounts++;
            NewBankAccount.SetupOperationTax();
            return NewBankAccount;
        }

    }

'''

public class BankAccount
 {
        public BankClient Client { get; private set; }
        public int BankID { get; private set; }
        public int BankAccountID { get; private set;}
        public double BankBalance { get; private set; }

        public double OperationTax { get; private set; }

        public BankAccount(string BankOwnerName, string BankOwnerCPF, bool InbIsWoman, int InBankID, int InBankAccountID, double InitialBalance)
        {


            Client = new BankClient(BankOwnerName, BankOwnerCPF, InbIsWoman);

            if(InBankID <= 0 || InBankAccountID <= 0)
            {

                throw new ArgumentException("The Bank ID or/BankAccount ID has 0 value. Please put a non zero value");
            }

            BankID = InBankID;
            BankAccountID = InBankAccountID;


            if (InitialBalance > 0)
            {
                BankBalance = InitialBalance;

            }
        }
}

A ideia é justamente impedir que ele consiga criar uma conta, exemplo, no Program.cs de um Console Application utilizando somente o construtor da BankAccount. Eu preciso obrigar isso usando algum jeito da IDE pra que dê um erro de compilação se ele fizer errado.

Se eu coloco a classe da conta como Internal eu consigo evitar que ele use o construtor no program.cs, porém dá problema de acessibilidade no Bank, pq o método do Bank (CreateBankAccount) retorna ela.

Hum, você sabe qua na prática a gente não tem muito esse tipo de preocupação pq esse programa é tipo muito ficticio.

Mas dá uma olhada nesse link e veja se ele te atende https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/keywords/accessibility-levels

É, talvez o jeito seja:

0) Deixar a classe BankAccount pública

1) fazer esse Construtor da BankAccount ser interno, assim o banco consegue usar. Mas outra classe fora da minha biblioteca não consegue

2) Faço um construtor que não aceita nenhum argumento com algum log ou exception pra ensinar o cara que não é assim que usa. Já que o esquema de ponteiros do C# não é igual ao de C++

solução!

Pelo que tenho reparado ponteiros não é com C# rsrsrs. C# é uma linguagem muito amarrada, onde tudo tem que estar em seu duvido lugar pra funcionar.