简体   繁体   中英

NullReferenceException when trying to add a new object to a list using inheritance

I am having an issue adding a new Account() to a list that is in FileAccountRepository.cs , I am still learning about inheritance, so there might be something that I do not know. In PremiumAccountTestRepository.cs , I am trying to pass the _account that is a new Account() with properties and try to add it to the list that is in FileAccountRepository.cs . The error message I get is that _fileAccountRepository was null on PremiumAccountTestRepository.cs . Would like to know the reason I cannot add to the list that is FileAccountRepository.cs ?

FileAccountRepository.cs

public class FileAccountRepository : IAccountRepository
{
    public List<Account> fileAccounts = new List<Account>();

    public FileAccountRepository(string mode)
    {
        GetUsers(mode);
    }        

    public void GetUsers(string mode) {            
        var dictionaryOfModes = new Dictionary<string, string>
        {
            ["FreeTest"] = "F",
            ["BasicTest"] = "B",
            ["PremiumTest"] = "P"
        };

        string path = @".\Accounts.txt";
        string[] rows = File.ReadAllLines(path);

        for (int i = 1; i < rows.Length; i++)
        {
            string[] columns = rows[i].Split(',');

            if (columns[3] == dictionaryOfModes[mode])
            {
                Account _account = new Account();
                _account.AccountNumber = columns[0];
                _account.Name = columns[1];
                _account.Balance = Decimal.Parse(columns[2]);
                if (columns[3] == "F")
                {
                    _account.Type = AccountType.Free;
                }
                else if (columns[3] == "B")
                {
                    _account.Type = AccountType.Basic;
                }
                else if (columns[3] == "P")
                {
                    _account.Type = AccountType.Premium;
                }

                //fileAccounts.Add(_account);
                StoreAccounts(_account);
            }
        }            
    }

    public Account LoadAccount(string AccountNumber)
    {
        return fileAccounts.FirstOrDefault(x => x.AccountNumber == AccountNumber);
    }

    public void SaveAccount(Account account)
    {
        //_account = account;
    }

    public void StoreAccounts(Account addAccount)
    {
        fileAccounts.Add(addAccount);
    }
}

PremiumAccountTestRepository.cs

public class PremiumAccountTestRepository : IAccountRepository
{
    private FileAccountRepository _fileAccountRepository;        

    public PremiumAccountTestRepository(FileAccountRepository fileAccountRepository)
    {
        _fileAccountRepository = fileAccountRepository;
    }

    public PremiumAccountTestRepository()
    {
        StoreAccounts(_account);
    }

    private static Account _account = new Account
    {
        Name = "Premium Account",
        Balance = 100M,
        AccountNumber = "44444",
        Type = AccountType.Premium
    };

    public Account LoadAccount(string AccountNumber)
    {

        if (_fileAccountRepository.fileAccounts.Any(x => x.AccountNumber == AccountNumber))
        {
            return _account;
        }

        return null;
    }

    public void SaveAccount(Account account)
    {
        _account = account;            
    } 

    public void StoreAccounts(Account addAccount)
    {
        _fileAccountRepository.fileAccounts.Add(addAccount); //_fileAccountRepository was null.
    }
}

AccountManagerFactory.cs

public static AccountManager Create()
    {
        string mode = ConfigurationManager.AppSettings["Mode"].ToString();

        switch (mode)
        {
            case "FreeTest":
                return new AccountManager(new FileAccountRepository(mode), new FreeAccountTestRepository());                    
            case "BasicTest":
                return new AccountManager(new FileAccountRepository(mode), new BasicAccountTestRepository());
            case "PremiumTest":
                return new AccountManager(new FileAccountRepository(mode), new PremiumAccountTestRepository());

            default:
                throw new Exception("Mode value in app config is not valid");
        }


    }

Try this code, I was not able to test it :

  public class PremiumAccountTestRepository : IAccountRepository
    {
    private FileAccountRepository _fileAccountRepository;
    private Account _account;   

    public PremiumAccountTestRepository(FileAccountRepository fileAccountRepository)
    {
        _fileAccountRepository = fileAccountRepository;

        _account= new Account
        {
            Name = "Premium Account",
            Balance = 100M,
            AccountNumber = "44444",
            Type = AccountType.Premium
        };


        StoreAccounts(_account);
    }


    public Account LoadAccount(string AccountNumber)
    {

        if (_fileAccountRepository.fileAccounts.Any(x => x.AccountNumber == AccountNumber))
        {
            return _account;
        }

        return null;
    }

    public void SaveAccount(Account account)
    {
        _account = account;            
    } 

    public void StoreAccounts(Account addAccount)
    {
        _fileAccountRepository.fileAccounts.Add(addAccount); //_fileAccountRepository was 
                                                                  null.
    }
   }

The issue in your code is that you have two constructors, _fileAccountRepository is not initialized with the dependency injection because of the other empty constructor

_fileAccountRepository is set in exactly one place in your code, in

public PremiumAccountTestRepository(FileAccountRepository fileAccountRepository)

The second creator

public PremiumAccountTestRepository()

Does not set it, so it will be null.

I suggest putting a break in both creators and see which is being called, and then you will know where from.

I don't see the top level driving code in your posting. I strongly suspect that the second form of the creator is getting called, and thus _fileAccountRepository is null.

what happens if this line is altered from

private FileAccountRepository _fileAccountRepository

to

private FileAccountRepository _fileAccountRepository = new FileAccountRepository()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM