How do I store elements in a list in ascending order that come from two other list C#?
The problem I am having is displaying items from my list in ascending order. I understand the problem that is creating this issue which is I am adding caccounts to the List and then adding saccounts to the list but i am not sure of any other way I can do this. The outcome should be to display the accounts in whatever order they were created which is dependent on the user. So as you see by the image below it is storing and displaying all created checking accounts first then savings accounts which is incorrect. It should show the in the order they were created. As you see from the image below the items are out of order. It should show Savings account 1 first then Checking account 2 and so on.
This is the code that is adding the items to this list and is creating the problem
List<Account> accounts = new List<Account>();
accounts.AddRange(caccounts);
accounts.AddRange(saccounts);
foreach (Account account in accounts)
List<Transaction> transactions = account.closeMonth();
allTransactions.AddRange(transactions);
This code shows the list I am adding saccounts and caccounts to
List<SavingsAccount> saccounts = new List<SavingsAccount>();
List<CheckingAccount> caccounts = new List<CheckingAccount>();
List<Transaction> allTransactions = new List<Transaction>();
This is code that I have in my checking class and savings class that override close month in the abstract account class
public override List<Transaction> closeMonth()
var transactions = new List<Transaction>();
var endString = new Transaction();
string reportString = ("Checking account: " + AccountID.ToString() +
" has a balance of $" + endingBalance.ToString());
endString.EndOfMonth = reportString;
transactions.Add(endString);
return transactions;
This is the property for the AccountID and i have this in the checking and savings class
class SavingsAccount : Account
public override int AccountID get; set;
When the account is originally created this is the code that assigns the AccountID
if (checkingRadioButton1.Checked == true)
_nextIndex++;
transactionLabel5.Text = "Checking Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
caccounts.Add(new CheckingAccount(balance)
AccountID = _nextIndex,
Student = isStudent
);
else if (savingsRadioButton2.Checked == true)
_nextIndex++;
transactionLabel5.Text = "Savings Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
saccounts.Add(new SavingsAccount(balance)
AccountID = _nextIndex,
Senior = isSenior
);
c#
add a comment |
The problem I am having is displaying items from my list in ascending order. I understand the problem that is creating this issue which is I am adding caccounts to the List and then adding saccounts to the list but i am not sure of any other way I can do this. The outcome should be to display the accounts in whatever order they were created which is dependent on the user. So as you see by the image below it is storing and displaying all created checking accounts first then savings accounts which is incorrect. It should show the in the order they were created. As you see from the image below the items are out of order. It should show Savings account 1 first then Checking account 2 and so on.
This is the code that is adding the items to this list and is creating the problem
List<Account> accounts = new List<Account>();
accounts.AddRange(caccounts);
accounts.AddRange(saccounts);
foreach (Account account in accounts)
List<Transaction> transactions = account.closeMonth();
allTransactions.AddRange(transactions);
This code shows the list I am adding saccounts and caccounts to
List<SavingsAccount> saccounts = new List<SavingsAccount>();
List<CheckingAccount> caccounts = new List<CheckingAccount>();
List<Transaction> allTransactions = new List<Transaction>();
This is code that I have in my checking class and savings class that override close month in the abstract account class
public override List<Transaction> closeMonth()
var transactions = new List<Transaction>();
var endString = new Transaction();
string reportString = ("Checking account: " + AccountID.ToString() +
" has a balance of $" + endingBalance.ToString());
endString.EndOfMonth = reportString;
transactions.Add(endString);
return transactions;
This is the property for the AccountID and i have this in the checking and savings class
class SavingsAccount : Account
public override int AccountID get; set;
When the account is originally created this is the code that assigns the AccountID
if (checkingRadioButton1.Checked == true)
_nextIndex++;
transactionLabel5.Text = "Checking Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
caccounts.Add(new CheckingAccount(balance)
AccountID = _nextIndex,
Student = isStudent
);
else if (savingsRadioButton2.Checked == true)
_nextIndex++;
transactionLabel5.Text = "Savings Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
saccounts.Add(new SavingsAccount(balance)
AccountID = _nextIndex,
Senior = isSenior
);
c#
1
I think you have to store an ID that is unique over both lists or a creation date or something like this. Then you can union both lists and then do anorder by
– Josef Biehler
Nov 13 '18 at 22:50
@Josef Biehler I have never used a union or order by but I will google it and see what that does. If you have the time can you provide a sample code of what you are talking about?
– Demond
Nov 13 '18 at 23:06
FYI, yourcloseMonth()
method can be reduced to one line:return new List<Transaction> new Transaction EndOfMonth = $"Checking account: AccountID has a balance of $endingBalance";
– Rufus L
Nov 14 '18 at 0:12
1
Why do you overrideAccountID
(i.e. why isAccount
abstract)? Why not just use the base class? For that matter, how are theCheckingAccount
andSavingsAccount
class different from each other, or from theAccount
base class? It feels like this code is unnecessarily complicated, but maybe I'm not seeing the big picture.
– Rufus L
Nov 14 '18 at 0:16
add a comment |
The problem I am having is displaying items from my list in ascending order. I understand the problem that is creating this issue which is I am adding caccounts to the List and then adding saccounts to the list but i am not sure of any other way I can do this. The outcome should be to display the accounts in whatever order they were created which is dependent on the user. So as you see by the image below it is storing and displaying all created checking accounts first then savings accounts which is incorrect. It should show the in the order they were created. As you see from the image below the items are out of order. It should show Savings account 1 first then Checking account 2 and so on.
This is the code that is adding the items to this list and is creating the problem
List<Account> accounts = new List<Account>();
accounts.AddRange(caccounts);
accounts.AddRange(saccounts);
foreach (Account account in accounts)
List<Transaction> transactions = account.closeMonth();
allTransactions.AddRange(transactions);
This code shows the list I am adding saccounts and caccounts to
List<SavingsAccount> saccounts = new List<SavingsAccount>();
List<CheckingAccount> caccounts = new List<CheckingAccount>();
List<Transaction> allTransactions = new List<Transaction>();
This is code that I have in my checking class and savings class that override close month in the abstract account class
public override List<Transaction> closeMonth()
var transactions = new List<Transaction>();
var endString = new Transaction();
string reportString = ("Checking account: " + AccountID.ToString() +
" has a balance of $" + endingBalance.ToString());
endString.EndOfMonth = reportString;
transactions.Add(endString);
return transactions;
This is the property for the AccountID and i have this in the checking and savings class
class SavingsAccount : Account
public override int AccountID get; set;
When the account is originally created this is the code that assigns the AccountID
if (checkingRadioButton1.Checked == true)
_nextIndex++;
transactionLabel5.Text = "Checking Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
caccounts.Add(new CheckingAccount(balance)
AccountID = _nextIndex,
Student = isStudent
);
else if (savingsRadioButton2.Checked == true)
_nextIndex++;
transactionLabel5.Text = "Savings Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
saccounts.Add(new SavingsAccount(balance)
AccountID = _nextIndex,
Senior = isSenior
);
c#
The problem I am having is displaying items from my list in ascending order. I understand the problem that is creating this issue which is I am adding caccounts to the List and then adding saccounts to the list but i am not sure of any other way I can do this. The outcome should be to display the accounts in whatever order they were created which is dependent on the user. So as you see by the image below it is storing and displaying all created checking accounts first then savings accounts which is incorrect. It should show the in the order they were created. As you see from the image below the items are out of order. It should show Savings account 1 first then Checking account 2 and so on.
This is the code that is adding the items to this list and is creating the problem
List<Account> accounts = new List<Account>();
accounts.AddRange(caccounts);
accounts.AddRange(saccounts);
foreach (Account account in accounts)
List<Transaction> transactions = account.closeMonth();
allTransactions.AddRange(transactions);
This code shows the list I am adding saccounts and caccounts to
List<SavingsAccount> saccounts = new List<SavingsAccount>();
List<CheckingAccount> caccounts = new List<CheckingAccount>();
List<Transaction> allTransactions = new List<Transaction>();
This is code that I have in my checking class and savings class that override close month in the abstract account class
public override List<Transaction> closeMonth()
var transactions = new List<Transaction>();
var endString = new Transaction();
string reportString = ("Checking account: " + AccountID.ToString() +
" has a balance of $" + endingBalance.ToString());
endString.EndOfMonth = reportString;
transactions.Add(endString);
return transactions;
This is the property for the AccountID and i have this in the checking and savings class
class SavingsAccount : Account
public override int AccountID get; set;
When the account is originally created this is the code that assigns the AccountID
if (checkingRadioButton1.Checked == true)
_nextIndex++;
transactionLabel5.Text = "Checking Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
caccounts.Add(new CheckingAccount(balance)
AccountID = _nextIndex,
Student = isStudent
);
else if (savingsRadioButton2.Checked == true)
_nextIndex++;
transactionLabel5.Text = "Savings Account: #" + _nextIndex +
" created with a starting balance of $" + balance;
accountTextBox1.Text = "" + _nextIndex;
saccounts.Add(new SavingsAccount(balance)
AccountID = _nextIndex,
Senior = isSenior
);
c#
c#
edited Nov 14 '18 at 0:09
Rufus L
17.7k31531
17.7k31531
asked Nov 13 '18 at 22:40
DemondDemond
545
545
1
I think you have to store an ID that is unique over both lists or a creation date or something like this. Then you can union both lists and then do anorder by
– Josef Biehler
Nov 13 '18 at 22:50
@Josef Biehler I have never used a union or order by but I will google it and see what that does. If you have the time can you provide a sample code of what you are talking about?
– Demond
Nov 13 '18 at 23:06
FYI, yourcloseMonth()
method can be reduced to one line:return new List<Transaction> new Transaction EndOfMonth = $"Checking account: AccountID has a balance of $endingBalance";
– Rufus L
Nov 14 '18 at 0:12
1
Why do you overrideAccountID
(i.e. why isAccount
abstract)? Why not just use the base class? For that matter, how are theCheckingAccount
andSavingsAccount
class different from each other, or from theAccount
base class? It feels like this code is unnecessarily complicated, but maybe I'm not seeing the big picture.
– Rufus L
Nov 14 '18 at 0:16
add a comment |
1
I think you have to store an ID that is unique over both lists or a creation date or something like this. Then you can union both lists and then do anorder by
– Josef Biehler
Nov 13 '18 at 22:50
@Josef Biehler I have never used a union or order by but I will google it and see what that does. If you have the time can you provide a sample code of what you are talking about?
– Demond
Nov 13 '18 at 23:06
FYI, yourcloseMonth()
method can be reduced to one line:return new List<Transaction> new Transaction EndOfMonth = $"Checking account: AccountID has a balance of $endingBalance";
– Rufus L
Nov 14 '18 at 0:12
1
Why do you overrideAccountID
(i.e. why isAccount
abstract)? Why not just use the base class? For that matter, how are theCheckingAccount
andSavingsAccount
class different from each other, or from theAccount
base class? It feels like this code is unnecessarily complicated, but maybe I'm not seeing the big picture.
– Rufus L
Nov 14 '18 at 0:16
1
1
I think you have to store an ID that is unique over both lists or a creation date or something like this. Then you can union both lists and then do an
order by
– Josef Biehler
Nov 13 '18 at 22:50
I think you have to store an ID that is unique over both lists or a creation date or something like this. Then you can union both lists and then do an
order by
– Josef Biehler
Nov 13 '18 at 22:50
@Josef Biehler I have never used a union or order by but I will google it and see what that does. If you have the time can you provide a sample code of what you are talking about?
– Demond
Nov 13 '18 at 23:06
@Josef Biehler I have never used a union or order by but I will google it and see what that does. If you have the time can you provide a sample code of what you are talking about?
– Demond
Nov 13 '18 at 23:06
FYI, your
closeMonth()
method can be reduced to one line: return new List<Transaction> new Transaction EndOfMonth = $"Checking account: AccountID has a balance of $endingBalance";
– Rufus L
Nov 14 '18 at 0:12
FYI, your
closeMonth()
method can be reduced to one line: return new List<Transaction> new Transaction EndOfMonth = $"Checking account: AccountID has a balance of $endingBalance";
– Rufus L
Nov 14 '18 at 0:12
1
1
Why do you override
AccountID
(i.e. why is Account
abstract)? Why not just use the base class? For that matter, how are the CheckingAccount
and SavingsAccount
class different from each other, or from the Account
base class? It feels like this code is unnecessarily complicated, but maybe I'm not seeing the big picture.– Rufus L
Nov 14 '18 at 0:16
Why do you override
AccountID
(i.e. why is Account
abstract)? Why not just use the base class? For that matter, how are the CheckingAccount
and SavingsAccount
class different from each other, or from the Account
base class? It feels like this code is unnecessarily complicated, but maybe I'm not seeing the big picture.– Rufus L
Nov 14 '18 at 0:16
add a comment |
3 Answers
3
active
oldest
votes
You could use OrderBy
on the collection.
var orderedTransactions = allTransactions.OrderBy(x=>x.AccountId).ToList();
Of course you would need to have that CreateDate or whatever property you want ordered by in your object.
I have a property for AccountId so are you stating i can do an Order By using it?
– Demond
Nov 13 '18 at 23:08
Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.
– NoSaidTheCompiler
Nov 13 '18 at 23:10
Wonderful. This worked.
– Demond
Nov 14 '18 at 17:52
add a comment |
Instead of using this code to merge accounts into one list
List<Account> accounts = new List<Account>();
accounts.AddRange(caccounts);
accounts.AddRange(saccounts);
foreach (Account account in accounts)
List<Transaction> transactions = account.closeMonth();
allTransactions.AddRange(transactions);
you can use this code
List<Account> accounts = new List<Account>();
int saccountsAdded = 0;
int caccountsAdded = 0;
for (int i = 0; i < saccounts.Count + caccounts.Count; i++)
if(saccountsAdded == saccounts.Count)
accounts[i] = caccounts[caccountsAdded++];
continue;
if (caccountsAdded == caccounts.Count)
accounts[i] = saccounts[saccountsAdded++];
continue;
if (saccounts[saccountsAdded].AccountID > caccounts[caccountsAdded].AccountID)
accounts[i] = caccounts[caccountsAdded ++];
else
accounts[i] = saccounts[saccountsAdded ++];
In my case, you are sorting accounts when you are combining them and then your accounts list will be ordered.
You can also use the solution from NoSaidTheCompiler, the only difference is that I am sorting and populating the list at the same time and he firstly populates the list and sorts after the list has been populated
add a comment |
The short answer is that you can order your Transactions
by the AccountID
using the System.Linq
extension method OrderBy
(along with a .SelectMany
method call to flatten each account's transaction list) before you output them:
List<Transaction> transactions = accounts
.OrderBy(a => a.AccountID)
.SelectMany(a => a.closeMonth())
.ToList();
Other thoughts
As I was answering your question, I couldn't figure out why Account
was abstract, or why there was a separate class for CheckingAccount
and SavingsAccount
, because I couldn't see a difference between the two and it felt so redundant to override all these abstract properties and methods with the exact same code in two different classes.
With that in mind, I felt compelled to share some thoughts which may or may not apply to your specific situation. Note that I have never written a banking app before, so there are probably many things I'm not thinkning of - just wanted to share this in case it helps.
Accounts
To me, an account is an account. There may be different rules associated with one type or another, but those can be defined by the Bank
that creates the accounts, and the class could have a List<Rule> AccountRules
that would be set based on that particular bank's policies (i.e. perhaps there is a minimum balance for a Checking account, but not a Savings account, or they have different interest rate schedules, or something else, but nothing that I can think of that is inherently different).
But in the end, an account is a repository for a decimal amount which can be changed by a Withdrawl
or a Deposit
(or an Interest
accruement).
Transactions
Also, the closeMonth()
method seemed really strange to me. It returns a List<Transaction>
that contains a single item. Instead, I think an Account
should have a List<Transaction>
that gets populated from every public method - even balance inquiries. Then this list can be queried to get the activities within a particular time frame, such as a month or a year (by filtering on the Transaction.Timestamp
property). Or it could be queried to get different types of transactions (by filtering on the Transaction.TransactionType
property).
To simplify adding a new transaction to the list, I added a private AddTransaction
method that takes in a Transaction.Type
and a description of the transaction. It then creates the Transaction
and adds it to the list. Also notice that the Transaction
class automatically adds the current DateTime
as a Timestamp
, so there's no need to worry about that on the client side.
Code
To prevent race conditions where Deposit
and Withdrawl
are called at the same time from different threads, I added some lock()
blocks around any code that accessed Balance
.
I also added an override to the ToString
method on the Transaction
class so that it was easier to output the details of each transaction.
Another item of interest is that you can format a decimal
as currency by using the C
format string (i.e. if you have decimal balance = 5M;
you can do balance.ToString("C")
or "balance:C"
and the string result will be "$5.00"
in the U.S. or "£5.00"
in England).
So the classes might then look something like the following:
public class Transaction
public enum Type Open, Close, Deposit, Withdrawl, Inquiry, Other
public Type TransactionType get;
public string Description get;
public DateTime Timestamp get;
public Transaction(Type transactionType, string description)
TransactionType = transactionType;
Description = description;
Timestamp = DateTime.Now;
public override string ToString()
return $"Timestamp: TransactionType - Description";
public class Account
public enum Type Checking, Savings
public Type AccountType get;
public int Id get;
public List<Transaction> Transactions get; private set;
private static readonly object IdLock = new object();
private static int _lastAccountId;
private readonly object balanceLock = new object();
private decimal balance;
public Account(decimal initialDeposit, Type accountType)
if (initialDeposit < 0)
throw new ArgumentOutOfRangeException("initialDeposit cannot be negative");
AccountType = accountType;
balance = initialDeposit;
lock (IdLock)
Id = ++_lastAccountId;
AddTransaction(Transaction.Type.Open,
$"AccountType account Id Id created with a deposit of: balance:C.");
public void Deposit(decimal amount)
if (amount < 0)
throw new ArgumentOutOfRangeException("Deposit amount cannot be negative");
lock (balanceLock)
balance += amount;
AddTransaction(Transaction.Type.Deposit,
$"amount was deposited. New balance: balance:C.");
public void Withdraw(decimal amount)
if (amount < 0)
throw new ArgumentOutOfRangeException("Withdrawl amount cannot be negative");
if (amount > balance)
throw new ArgumentOutOfRangeException(
"Cannot withdraw more money than the account contains");
lock (balanceLock)
balance -= amount;
AddTransaction(Transaction.Type.Withdrawl,
$"amount was withdrawn. New balance: balance:C.");
public decimal GetBalance()
lock (balanceLock)
AddTransaction(Transaction.Type.Inquiry,
$"Balance inquiry made. Balance: balance:C.");
return balance;
private void AddTransaction(Transaction.Type transactionType, string description)
if (Transactions == null) Transactions = new List<Transaction>();
Transactions.Add(new Transaction(transactionType, description));
So, with all that, here's an example that populates a list of accounts in the same order that you have shown in your form above, with an example of how you can output all the transactions for the accounts ordered by the account id:
static void Main(string args)
// Adding accounts in the same order as they appear on your form
var accounts = new List<Account>
new Account(293.05M, Account.Type.Checking),
new Account(293.05M, Account.Type.Checking),
new Account(300M, Account.Type.Savings),
new Account(300M, Account.Type.Savings),
;
// Sort transactions by account Id
List<Transaction> transactions = accounts
.OrderBy(a => a.Id)
.SelectMany(a => a.Transactions)
.ToList();
// Write results to Console
transactions.ForEach(Console.WriteLine);
GetKeyFromUser("nDone! Press any key to exit...");
Output
Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.
– Demond
Nov 14 '18 at 17:55
Oh, that makes sense. :)
– Rufus L
Nov 14 '18 at 18:26
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53290586%2fhow-do-i-store-elements-in-a-list-in-ascending-order-that-come-from-two-other-li%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
You could use OrderBy
on the collection.
var orderedTransactions = allTransactions.OrderBy(x=>x.AccountId).ToList();
Of course you would need to have that CreateDate or whatever property you want ordered by in your object.
I have a property for AccountId so are you stating i can do an Order By using it?
– Demond
Nov 13 '18 at 23:08
Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.
– NoSaidTheCompiler
Nov 13 '18 at 23:10
Wonderful. This worked.
– Demond
Nov 14 '18 at 17:52
add a comment |
You could use OrderBy
on the collection.
var orderedTransactions = allTransactions.OrderBy(x=>x.AccountId).ToList();
Of course you would need to have that CreateDate or whatever property you want ordered by in your object.
I have a property for AccountId so are you stating i can do an Order By using it?
– Demond
Nov 13 '18 at 23:08
Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.
– NoSaidTheCompiler
Nov 13 '18 at 23:10
Wonderful. This worked.
– Demond
Nov 14 '18 at 17:52
add a comment |
You could use OrderBy
on the collection.
var orderedTransactions = allTransactions.OrderBy(x=>x.AccountId).ToList();
Of course you would need to have that CreateDate or whatever property you want ordered by in your object.
You could use OrderBy
on the collection.
var orderedTransactions = allTransactions.OrderBy(x=>x.AccountId).ToList();
Of course you would need to have that CreateDate or whatever property you want ordered by in your object.
edited Nov 13 '18 at 23:12
answered Nov 13 '18 at 22:52
NoSaidTheCompilerNoSaidTheCompiler
1,77721834
1,77721834
I have a property for AccountId so are you stating i can do an Order By using it?
– Demond
Nov 13 '18 at 23:08
Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.
– NoSaidTheCompiler
Nov 13 '18 at 23:10
Wonderful. This worked.
– Demond
Nov 14 '18 at 17:52
add a comment |
I have a property for AccountId so are you stating i can do an Order By using it?
– Demond
Nov 13 '18 at 23:08
Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.
– NoSaidTheCompiler
Nov 13 '18 at 23:10
Wonderful. This worked.
– Demond
Nov 14 '18 at 17:52
I have a property for AccountId so are you stating i can do an Order By using it?
– Demond
Nov 13 '18 at 23:08
I have a property for AccountId so are you stating i can do an Order By using it?
– Demond
Nov 13 '18 at 23:08
Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.
– NoSaidTheCompiler
Nov 13 '18 at 23:10
Yes you can order by any property and the collection will be ordered accordingly. Just change .OrderBy(x=>x.AccountId).ToList(); Use .OrderByDesc(x=> x.AccountId) if you need in desc order.
– NoSaidTheCompiler
Nov 13 '18 at 23:10
Wonderful. This worked.
– Demond
Nov 14 '18 at 17:52
Wonderful. This worked.
– Demond
Nov 14 '18 at 17:52
add a comment |
Instead of using this code to merge accounts into one list
List<Account> accounts = new List<Account>();
accounts.AddRange(caccounts);
accounts.AddRange(saccounts);
foreach (Account account in accounts)
List<Transaction> transactions = account.closeMonth();
allTransactions.AddRange(transactions);
you can use this code
List<Account> accounts = new List<Account>();
int saccountsAdded = 0;
int caccountsAdded = 0;
for (int i = 0; i < saccounts.Count + caccounts.Count; i++)
if(saccountsAdded == saccounts.Count)
accounts[i] = caccounts[caccountsAdded++];
continue;
if (caccountsAdded == caccounts.Count)
accounts[i] = saccounts[saccountsAdded++];
continue;
if (saccounts[saccountsAdded].AccountID > caccounts[caccountsAdded].AccountID)
accounts[i] = caccounts[caccountsAdded ++];
else
accounts[i] = saccounts[saccountsAdded ++];
In my case, you are sorting accounts when you are combining them and then your accounts list will be ordered.
You can also use the solution from NoSaidTheCompiler, the only difference is that I am sorting and populating the list at the same time and he firstly populates the list and sorts after the list has been populated
add a comment |
Instead of using this code to merge accounts into one list
List<Account> accounts = new List<Account>();
accounts.AddRange(caccounts);
accounts.AddRange(saccounts);
foreach (Account account in accounts)
List<Transaction> transactions = account.closeMonth();
allTransactions.AddRange(transactions);
you can use this code
List<Account> accounts = new List<Account>();
int saccountsAdded = 0;
int caccountsAdded = 0;
for (int i = 0; i < saccounts.Count + caccounts.Count; i++)
if(saccountsAdded == saccounts.Count)
accounts[i] = caccounts[caccountsAdded++];
continue;
if (caccountsAdded == caccounts.Count)
accounts[i] = saccounts[saccountsAdded++];
continue;
if (saccounts[saccountsAdded].AccountID > caccounts[caccountsAdded].AccountID)
accounts[i] = caccounts[caccountsAdded ++];
else
accounts[i] = saccounts[saccountsAdded ++];
In my case, you are sorting accounts when you are combining them and then your accounts list will be ordered.
You can also use the solution from NoSaidTheCompiler, the only difference is that I am sorting and populating the list at the same time and he firstly populates the list and sorts after the list has been populated
add a comment |
Instead of using this code to merge accounts into one list
List<Account> accounts = new List<Account>();
accounts.AddRange(caccounts);
accounts.AddRange(saccounts);
foreach (Account account in accounts)
List<Transaction> transactions = account.closeMonth();
allTransactions.AddRange(transactions);
you can use this code
List<Account> accounts = new List<Account>();
int saccountsAdded = 0;
int caccountsAdded = 0;
for (int i = 0; i < saccounts.Count + caccounts.Count; i++)
if(saccountsAdded == saccounts.Count)
accounts[i] = caccounts[caccountsAdded++];
continue;
if (caccountsAdded == caccounts.Count)
accounts[i] = saccounts[saccountsAdded++];
continue;
if (saccounts[saccountsAdded].AccountID > caccounts[caccountsAdded].AccountID)
accounts[i] = caccounts[caccountsAdded ++];
else
accounts[i] = saccounts[saccountsAdded ++];
In my case, you are sorting accounts when you are combining them and then your accounts list will be ordered.
You can also use the solution from NoSaidTheCompiler, the only difference is that I am sorting and populating the list at the same time and he firstly populates the list and sorts after the list has been populated
Instead of using this code to merge accounts into one list
List<Account> accounts = new List<Account>();
accounts.AddRange(caccounts);
accounts.AddRange(saccounts);
foreach (Account account in accounts)
List<Transaction> transactions = account.closeMonth();
allTransactions.AddRange(transactions);
you can use this code
List<Account> accounts = new List<Account>();
int saccountsAdded = 0;
int caccountsAdded = 0;
for (int i = 0; i < saccounts.Count + caccounts.Count; i++)
if(saccountsAdded == saccounts.Count)
accounts[i] = caccounts[caccountsAdded++];
continue;
if (caccountsAdded == caccounts.Count)
accounts[i] = saccounts[saccountsAdded++];
continue;
if (saccounts[saccountsAdded].AccountID > caccounts[caccountsAdded].AccountID)
accounts[i] = caccounts[caccountsAdded ++];
else
accounts[i] = saccounts[saccountsAdded ++];
In my case, you are sorting accounts when you are combining them and then your accounts list will be ordered.
You can also use the solution from NoSaidTheCompiler, the only difference is that I am sorting and populating the list at the same time and he firstly populates the list and sorts after the list has been populated
edited Nov 13 '18 at 23:17
answered Nov 13 '18 at 23:08
Dusan RadovanovicDusan Radovanovic
437111
437111
add a comment |
add a comment |
The short answer is that you can order your Transactions
by the AccountID
using the System.Linq
extension method OrderBy
(along with a .SelectMany
method call to flatten each account's transaction list) before you output them:
List<Transaction> transactions = accounts
.OrderBy(a => a.AccountID)
.SelectMany(a => a.closeMonth())
.ToList();
Other thoughts
As I was answering your question, I couldn't figure out why Account
was abstract, or why there was a separate class for CheckingAccount
and SavingsAccount
, because I couldn't see a difference between the two and it felt so redundant to override all these abstract properties and methods with the exact same code in two different classes.
With that in mind, I felt compelled to share some thoughts which may or may not apply to your specific situation. Note that I have never written a banking app before, so there are probably many things I'm not thinkning of - just wanted to share this in case it helps.
Accounts
To me, an account is an account. There may be different rules associated with one type or another, but those can be defined by the Bank
that creates the accounts, and the class could have a List<Rule> AccountRules
that would be set based on that particular bank's policies (i.e. perhaps there is a minimum balance for a Checking account, but not a Savings account, or they have different interest rate schedules, or something else, but nothing that I can think of that is inherently different).
But in the end, an account is a repository for a decimal amount which can be changed by a Withdrawl
or a Deposit
(or an Interest
accruement).
Transactions
Also, the closeMonth()
method seemed really strange to me. It returns a List<Transaction>
that contains a single item. Instead, I think an Account
should have a List<Transaction>
that gets populated from every public method - even balance inquiries. Then this list can be queried to get the activities within a particular time frame, such as a month or a year (by filtering on the Transaction.Timestamp
property). Or it could be queried to get different types of transactions (by filtering on the Transaction.TransactionType
property).
To simplify adding a new transaction to the list, I added a private AddTransaction
method that takes in a Transaction.Type
and a description of the transaction. It then creates the Transaction
and adds it to the list. Also notice that the Transaction
class automatically adds the current DateTime
as a Timestamp
, so there's no need to worry about that on the client side.
Code
To prevent race conditions where Deposit
and Withdrawl
are called at the same time from different threads, I added some lock()
blocks around any code that accessed Balance
.
I also added an override to the ToString
method on the Transaction
class so that it was easier to output the details of each transaction.
Another item of interest is that you can format a decimal
as currency by using the C
format string (i.e. if you have decimal balance = 5M;
you can do balance.ToString("C")
or "balance:C"
and the string result will be "$5.00"
in the U.S. or "£5.00"
in England).
So the classes might then look something like the following:
public class Transaction
public enum Type Open, Close, Deposit, Withdrawl, Inquiry, Other
public Type TransactionType get;
public string Description get;
public DateTime Timestamp get;
public Transaction(Type transactionType, string description)
TransactionType = transactionType;
Description = description;
Timestamp = DateTime.Now;
public override string ToString()
return $"Timestamp: TransactionType - Description";
public class Account
public enum Type Checking, Savings
public Type AccountType get;
public int Id get;
public List<Transaction> Transactions get; private set;
private static readonly object IdLock = new object();
private static int _lastAccountId;
private readonly object balanceLock = new object();
private decimal balance;
public Account(decimal initialDeposit, Type accountType)
if (initialDeposit < 0)
throw new ArgumentOutOfRangeException("initialDeposit cannot be negative");
AccountType = accountType;
balance = initialDeposit;
lock (IdLock)
Id = ++_lastAccountId;
AddTransaction(Transaction.Type.Open,
$"AccountType account Id Id created with a deposit of: balance:C.");
public void Deposit(decimal amount)
if (amount < 0)
throw new ArgumentOutOfRangeException("Deposit amount cannot be negative");
lock (balanceLock)
balance += amount;
AddTransaction(Transaction.Type.Deposit,
$"amount was deposited. New balance: balance:C.");
public void Withdraw(decimal amount)
if (amount < 0)
throw new ArgumentOutOfRangeException("Withdrawl amount cannot be negative");
if (amount > balance)
throw new ArgumentOutOfRangeException(
"Cannot withdraw more money than the account contains");
lock (balanceLock)
balance -= amount;
AddTransaction(Transaction.Type.Withdrawl,
$"amount was withdrawn. New balance: balance:C.");
public decimal GetBalance()
lock (balanceLock)
AddTransaction(Transaction.Type.Inquiry,
$"Balance inquiry made. Balance: balance:C.");
return balance;
private void AddTransaction(Transaction.Type transactionType, string description)
if (Transactions == null) Transactions = new List<Transaction>();
Transactions.Add(new Transaction(transactionType, description));
So, with all that, here's an example that populates a list of accounts in the same order that you have shown in your form above, with an example of how you can output all the transactions for the accounts ordered by the account id:
static void Main(string args)
// Adding accounts in the same order as they appear on your form
var accounts = new List<Account>
new Account(293.05M, Account.Type.Checking),
new Account(293.05M, Account.Type.Checking),
new Account(300M, Account.Type.Savings),
new Account(300M, Account.Type.Savings),
;
// Sort transactions by account Id
List<Transaction> transactions = accounts
.OrderBy(a => a.Id)
.SelectMany(a => a.Transactions)
.ToList();
// Write results to Console
transactions.ForEach(Console.WriteLine);
GetKeyFromUser("nDone! Press any key to exit...");
Output
Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.
– Demond
Nov 14 '18 at 17:55
Oh, that makes sense. :)
– Rufus L
Nov 14 '18 at 18:26
add a comment |
The short answer is that you can order your Transactions
by the AccountID
using the System.Linq
extension method OrderBy
(along with a .SelectMany
method call to flatten each account's transaction list) before you output them:
List<Transaction> transactions = accounts
.OrderBy(a => a.AccountID)
.SelectMany(a => a.closeMonth())
.ToList();
Other thoughts
As I was answering your question, I couldn't figure out why Account
was abstract, or why there was a separate class for CheckingAccount
and SavingsAccount
, because I couldn't see a difference between the two and it felt so redundant to override all these abstract properties and methods with the exact same code in two different classes.
With that in mind, I felt compelled to share some thoughts which may or may not apply to your specific situation. Note that I have never written a banking app before, so there are probably many things I'm not thinkning of - just wanted to share this in case it helps.
Accounts
To me, an account is an account. There may be different rules associated with one type or another, but those can be defined by the Bank
that creates the accounts, and the class could have a List<Rule> AccountRules
that would be set based on that particular bank's policies (i.e. perhaps there is a minimum balance for a Checking account, but not a Savings account, or they have different interest rate schedules, or something else, but nothing that I can think of that is inherently different).
But in the end, an account is a repository for a decimal amount which can be changed by a Withdrawl
or a Deposit
(or an Interest
accruement).
Transactions
Also, the closeMonth()
method seemed really strange to me. It returns a List<Transaction>
that contains a single item. Instead, I think an Account
should have a List<Transaction>
that gets populated from every public method - even balance inquiries. Then this list can be queried to get the activities within a particular time frame, such as a month or a year (by filtering on the Transaction.Timestamp
property). Or it could be queried to get different types of transactions (by filtering on the Transaction.TransactionType
property).
To simplify adding a new transaction to the list, I added a private AddTransaction
method that takes in a Transaction.Type
and a description of the transaction. It then creates the Transaction
and adds it to the list. Also notice that the Transaction
class automatically adds the current DateTime
as a Timestamp
, so there's no need to worry about that on the client side.
Code
To prevent race conditions where Deposit
and Withdrawl
are called at the same time from different threads, I added some lock()
blocks around any code that accessed Balance
.
I also added an override to the ToString
method on the Transaction
class so that it was easier to output the details of each transaction.
Another item of interest is that you can format a decimal
as currency by using the C
format string (i.e. if you have decimal balance = 5M;
you can do balance.ToString("C")
or "balance:C"
and the string result will be "$5.00"
in the U.S. or "£5.00"
in England).
So the classes might then look something like the following:
public class Transaction
public enum Type Open, Close, Deposit, Withdrawl, Inquiry, Other
public Type TransactionType get;
public string Description get;
public DateTime Timestamp get;
public Transaction(Type transactionType, string description)
TransactionType = transactionType;
Description = description;
Timestamp = DateTime.Now;
public override string ToString()
return $"Timestamp: TransactionType - Description";
public class Account
public enum Type Checking, Savings
public Type AccountType get;
public int Id get;
public List<Transaction> Transactions get; private set;
private static readonly object IdLock = new object();
private static int _lastAccountId;
private readonly object balanceLock = new object();
private decimal balance;
public Account(decimal initialDeposit, Type accountType)
if (initialDeposit < 0)
throw new ArgumentOutOfRangeException("initialDeposit cannot be negative");
AccountType = accountType;
balance = initialDeposit;
lock (IdLock)
Id = ++_lastAccountId;
AddTransaction(Transaction.Type.Open,
$"AccountType account Id Id created with a deposit of: balance:C.");
public void Deposit(decimal amount)
if (amount < 0)
throw new ArgumentOutOfRangeException("Deposit amount cannot be negative");
lock (balanceLock)
balance += amount;
AddTransaction(Transaction.Type.Deposit,
$"amount was deposited. New balance: balance:C.");
public void Withdraw(decimal amount)
if (amount < 0)
throw new ArgumentOutOfRangeException("Withdrawl amount cannot be negative");
if (amount > balance)
throw new ArgumentOutOfRangeException(
"Cannot withdraw more money than the account contains");
lock (balanceLock)
balance -= amount;
AddTransaction(Transaction.Type.Withdrawl,
$"amount was withdrawn. New balance: balance:C.");
public decimal GetBalance()
lock (balanceLock)
AddTransaction(Transaction.Type.Inquiry,
$"Balance inquiry made. Balance: balance:C.");
return balance;
private void AddTransaction(Transaction.Type transactionType, string description)
if (Transactions == null) Transactions = new List<Transaction>();
Transactions.Add(new Transaction(transactionType, description));
So, with all that, here's an example that populates a list of accounts in the same order that you have shown in your form above, with an example of how you can output all the transactions for the accounts ordered by the account id:
static void Main(string args)
// Adding accounts in the same order as they appear on your form
var accounts = new List<Account>
new Account(293.05M, Account.Type.Checking),
new Account(293.05M, Account.Type.Checking),
new Account(300M, Account.Type.Savings),
new Account(300M, Account.Type.Savings),
;
// Sort transactions by account Id
List<Transaction> transactions = accounts
.OrderBy(a => a.Id)
.SelectMany(a => a.Transactions)
.ToList();
// Write results to Console
transactions.ForEach(Console.WriteLine);
GetKeyFromUser("nDone! Press any key to exit...");
Output
Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.
– Demond
Nov 14 '18 at 17:55
Oh, that makes sense. :)
– Rufus L
Nov 14 '18 at 18:26
add a comment |
The short answer is that you can order your Transactions
by the AccountID
using the System.Linq
extension method OrderBy
(along with a .SelectMany
method call to flatten each account's transaction list) before you output them:
List<Transaction> transactions = accounts
.OrderBy(a => a.AccountID)
.SelectMany(a => a.closeMonth())
.ToList();
Other thoughts
As I was answering your question, I couldn't figure out why Account
was abstract, or why there was a separate class for CheckingAccount
and SavingsAccount
, because I couldn't see a difference between the two and it felt so redundant to override all these abstract properties and methods with the exact same code in two different classes.
With that in mind, I felt compelled to share some thoughts which may or may not apply to your specific situation. Note that I have never written a banking app before, so there are probably many things I'm not thinkning of - just wanted to share this in case it helps.
Accounts
To me, an account is an account. There may be different rules associated with one type or another, but those can be defined by the Bank
that creates the accounts, and the class could have a List<Rule> AccountRules
that would be set based on that particular bank's policies (i.e. perhaps there is a minimum balance for a Checking account, but not a Savings account, or they have different interest rate schedules, or something else, but nothing that I can think of that is inherently different).
But in the end, an account is a repository for a decimal amount which can be changed by a Withdrawl
or a Deposit
(or an Interest
accruement).
Transactions
Also, the closeMonth()
method seemed really strange to me. It returns a List<Transaction>
that contains a single item. Instead, I think an Account
should have a List<Transaction>
that gets populated from every public method - even balance inquiries. Then this list can be queried to get the activities within a particular time frame, such as a month or a year (by filtering on the Transaction.Timestamp
property). Or it could be queried to get different types of transactions (by filtering on the Transaction.TransactionType
property).
To simplify adding a new transaction to the list, I added a private AddTransaction
method that takes in a Transaction.Type
and a description of the transaction. It then creates the Transaction
and adds it to the list. Also notice that the Transaction
class automatically adds the current DateTime
as a Timestamp
, so there's no need to worry about that on the client side.
Code
To prevent race conditions where Deposit
and Withdrawl
are called at the same time from different threads, I added some lock()
blocks around any code that accessed Balance
.
I also added an override to the ToString
method on the Transaction
class so that it was easier to output the details of each transaction.
Another item of interest is that you can format a decimal
as currency by using the C
format string (i.e. if you have decimal balance = 5M;
you can do balance.ToString("C")
or "balance:C"
and the string result will be "$5.00"
in the U.S. or "£5.00"
in England).
So the classes might then look something like the following:
public class Transaction
public enum Type Open, Close, Deposit, Withdrawl, Inquiry, Other
public Type TransactionType get;
public string Description get;
public DateTime Timestamp get;
public Transaction(Type transactionType, string description)
TransactionType = transactionType;
Description = description;
Timestamp = DateTime.Now;
public override string ToString()
return $"Timestamp: TransactionType - Description";
public class Account
public enum Type Checking, Savings
public Type AccountType get;
public int Id get;
public List<Transaction> Transactions get; private set;
private static readonly object IdLock = new object();
private static int _lastAccountId;
private readonly object balanceLock = new object();
private decimal balance;
public Account(decimal initialDeposit, Type accountType)
if (initialDeposit < 0)
throw new ArgumentOutOfRangeException("initialDeposit cannot be negative");
AccountType = accountType;
balance = initialDeposit;
lock (IdLock)
Id = ++_lastAccountId;
AddTransaction(Transaction.Type.Open,
$"AccountType account Id Id created with a deposit of: balance:C.");
public void Deposit(decimal amount)
if (amount < 0)
throw new ArgumentOutOfRangeException("Deposit amount cannot be negative");
lock (balanceLock)
balance += amount;
AddTransaction(Transaction.Type.Deposit,
$"amount was deposited. New balance: balance:C.");
public void Withdraw(decimal amount)
if (amount < 0)
throw new ArgumentOutOfRangeException("Withdrawl amount cannot be negative");
if (amount > balance)
throw new ArgumentOutOfRangeException(
"Cannot withdraw more money than the account contains");
lock (balanceLock)
balance -= amount;
AddTransaction(Transaction.Type.Withdrawl,
$"amount was withdrawn. New balance: balance:C.");
public decimal GetBalance()
lock (balanceLock)
AddTransaction(Transaction.Type.Inquiry,
$"Balance inquiry made. Balance: balance:C.");
return balance;
private void AddTransaction(Transaction.Type transactionType, string description)
if (Transactions == null) Transactions = new List<Transaction>();
Transactions.Add(new Transaction(transactionType, description));
So, with all that, here's an example that populates a list of accounts in the same order that you have shown in your form above, with an example of how you can output all the transactions for the accounts ordered by the account id:
static void Main(string args)
// Adding accounts in the same order as they appear on your form
var accounts = new List<Account>
new Account(293.05M, Account.Type.Checking),
new Account(293.05M, Account.Type.Checking),
new Account(300M, Account.Type.Savings),
new Account(300M, Account.Type.Savings),
;
// Sort transactions by account Id
List<Transaction> transactions = accounts
.OrderBy(a => a.Id)
.SelectMany(a => a.Transactions)
.ToList();
// Write results to Console
transactions.ForEach(Console.WriteLine);
GetKeyFromUser("nDone! Press any key to exit...");
Output
The short answer is that you can order your Transactions
by the AccountID
using the System.Linq
extension method OrderBy
(along with a .SelectMany
method call to flatten each account's transaction list) before you output them:
List<Transaction> transactions = accounts
.OrderBy(a => a.AccountID)
.SelectMany(a => a.closeMonth())
.ToList();
Other thoughts
As I was answering your question, I couldn't figure out why Account
was abstract, or why there was a separate class for CheckingAccount
and SavingsAccount
, because I couldn't see a difference between the two and it felt so redundant to override all these abstract properties and methods with the exact same code in two different classes.
With that in mind, I felt compelled to share some thoughts which may or may not apply to your specific situation. Note that I have never written a banking app before, so there are probably many things I'm not thinkning of - just wanted to share this in case it helps.
Accounts
To me, an account is an account. There may be different rules associated with one type or another, but those can be defined by the Bank
that creates the accounts, and the class could have a List<Rule> AccountRules
that would be set based on that particular bank's policies (i.e. perhaps there is a minimum balance for a Checking account, but not a Savings account, or they have different interest rate schedules, or something else, but nothing that I can think of that is inherently different).
But in the end, an account is a repository for a decimal amount which can be changed by a Withdrawl
or a Deposit
(or an Interest
accruement).
Transactions
Also, the closeMonth()
method seemed really strange to me. It returns a List<Transaction>
that contains a single item. Instead, I think an Account
should have a List<Transaction>
that gets populated from every public method - even balance inquiries. Then this list can be queried to get the activities within a particular time frame, such as a month or a year (by filtering on the Transaction.Timestamp
property). Or it could be queried to get different types of transactions (by filtering on the Transaction.TransactionType
property).
To simplify adding a new transaction to the list, I added a private AddTransaction
method that takes in a Transaction.Type
and a description of the transaction. It then creates the Transaction
and adds it to the list. Also notice that the Transaction
class automatically adds the current DateTime
as a Timestamp
, so there's no need to worry about that on the client side.
Code
To prevent race conditions where Deposit
and Withdrawl
are called at the same time from different threads, I added some lock()
blocks around any code that accessed Balance
.
I also added an override to the ToString
method on the Transaction
class so that it was easier to output the details of each transaction.
Another item of interest is that you can format a decimal
as currency by using the C
format string (i.e. if you have decimal balance = 5M;
you can do balance.ToString("C")
or "balance:C"
and the string result will be "$5.00"
in the U.S. or "£5.00"
in England).
So the classes might then look something like the following:
public class Transaction
public enum Type Open, Close, Deposit, Withdrawl, Inquiry, Other
public Type TransactionType get;
public string Description get;
public DateTime Timestamp get;
public Transaction(Type transactionType, string description)
TransactionType = transactionType;
Description = description;
Timestamp = DateTime.Now;
public override string ToString()
return $"Timestamp: TransactionType - Description";
public class Account
public enum Type Checking, Savings
public Type AccountType get;
public int Id get;
public List<Transaction> Transactions get; private set;
private static readonly object IdLock = new object();
private static int _lastAccountId;
private readonly object balanceLock = new object();
private decimal balance;
public Account(decimal initialDeposit, Type accountType)
if (initialDeposit < 0)
throw new ArgumentOutOfRangeException("initialDeposit cannot be negative");
AccountType = accountType;
balance = initialDeposit;
lock (IdLock)
Id = ++_lastAccountId;
AddTransaction(Transaction.Type.Open,
$"AccountType account Id Id created with a deposit of: balance:C.");
public void Deposit(decimal amount)
if (amount < 0)
throw new ArgumentOutOfRangeException("Deposit amount cannot be negative");
lock (balanceLock)
balance += amount;
AddTransaction(Transaction.Type.Deposit,
$"amount was deposited. New balance: balance:C.");
public void Withdraw(decimal amount)
if (amount < 0)
throw new ArgumentOutOfRangeException("Withdrawl amount cannot be negative");
if (amount > balance)
throw new ArgumentOutOfRangeException(
"Cannot withdraw more money than the account contains");
lock (balanceLock)
balance -= amount;
AddTransaction(Transaction.Type.Withdrawl,
$"amount was withdrawn. New balance: balance:C.");
public decimal GetBalance()
lock (balanceLock)
AddTransaction(Transaction.Type.Inquiry,
$"Balance inquiry made. Balance: balance:C.");
return balance;
private void AddTransaction(Transaction.Type transactionType, string description)
if (Transactions == null) Transactions = new List<Transaction>();
Transactions.Add(new Transaction(transactionType, description));
So, with all that, here's an example that populates a list of accounts in the same order that you have shown in your form above, with an example of how you can output all the transactions for the accounts ordered by the account id:
static void Main(string args)
// Adding accounts in the same order as they appear on your form
var accounts = new List<Account>
new Account(293.05M, Account.Type.Checking),
new Account(293.05M, Account.Type.Checking),
new Account(300M, Account.Type.Savings),
new Account(300M, Account.Type.Savings),
;
// Sort transactions by account Id
List<Transaction> transactions = accounts
.OrderBy(a => a.Id)
.SelectMany(a => a.Transactions)
.ToList();
// Write results to Console
transactions.ForEach(Console.WriteLine);
GetKeyFromUser("nDone! Press any key to exit...");
Output
answered Nov 14 '18 at 2:11
Rufus LRufus L
17.7k31531
17.7k31531
Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.
– Demond
Nov 14 '18 at 17:55
Oh, that makes sense. :)
– Rufus L
Nov 14 '18 at 18:26
add a comment |
Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.
– Demond
Nov 14 '18 at 17:55
Oh, that makes sense. :)
– Rufus L
Nov 14 '18 at 18:26
Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.
– Demond
Nov 14 '18 at 17:55
Wow thank you and this information you provided was very insightful. To answer your question I have it setup with and abstract account class and a checking and savings class to override it because this is an assignment which requires me to have it designed exactly as such. The information you have provided is very helpful and I thank you for it.
– Demond
Nov 14 '18 at 17:55
Oh, that makes sense. :)
– Rufus L
Nov 14 '18 at 18:26
Oh, that makes sense. :)
– Rufus L
Nov 14 '18 at 18:26
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53290586%2fhow-do-i-store-elements-in-a-list-in-ascending-order-that-come-from-two-other-li%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
I think you have to store an ID that is unique over both lists or a creation date or something like this. Then you can union both lists and then do an
order by
– Josef Biehler
Nov 13 '18 at 22:50
@Josef Biehler I have never used a union or order by but I will google it and see what that does. If you have the time can you provide a sample code of what you are talking about?
– Demond
Nov 13 '18 at 23:06
FYI, your
closeMonth()
method can be reduced to one line:return new List<Transaction> new Transaction EndOfMonth = $"Checking account: AccountID has a balance of $endingBalance";
– Rufus L
Nov 14 '18 at 0:12
1
Why do you override
AccountID
(i.e. why isAccount
abstract)? Why not just use the base class? For that matter, how are theCheckingAccount
andSavingsAccount
class different from each other, or from theAccount
base class? It feels like this code is unnecessarily complicated, but maybe I'm not seeing the big picture.– Rufus L
Nov 14 '18 at 0:16