What I am currently atempting to make is an inventory system. I wonder if I can store the current method and then open the inventory, and when I am done there, reopen/recall the previus method that ran.
You haven't provided very much information but I can tell you don't want to store a method, you want to store an object.
An object is an instance of a class. Depending on the kind of class you have you can either create multiple instances of a class and instantiate them multiple times across your application. Or alternatively you can create single instances of an object that you use throughout your entire application/game.
From the sounds of it, you want to use a singleton class that retains the current values of the user's inventory. So if you interact with the inventory class in one part of your program, you would like to then view and interact with the same previously modified values stored within the singleton from another part of your program.
I can't give you a concrete answer to your problem, but a possible Singleton class for your use case would look something like this;
public sealed class Inventory
{
private static readonly Inventoryinstance = new Inventory();
// Explicit static constructor to tell C# compiler
// not to mark type as before field init
static Inventory()
{
}
private Inventory()
{
// optionally, pre-populate with data stored in database when constructed
}
public static Inventory Instance
{
get
{
return instance;
}
}
public List<InventoryItem> InventoryItems { get; set; } = new List<InventoryItem>();
public void AddItemToInventory(InventoryItem item) {
InventoryItems.Add(item);
}
public void RemoveItemFromInventory(InventoryItem item) {
InventoryItems.Remove(item);
}
}
You can use this site for reference - https://csharpindepth.com/articles/singleton
If you have an application that utilises DI, you can create singleton instances that are injectable into your other app classes. This is a better way of handling singletons as they are handled by an IoC system rather than being made static for the entire application to access.
Related
Let's say I have two classes.
One class User which has a lot of instances and one AccountInterface which is handling Database/File System Queries and might be accessed by every user.
Lets say, User looks like this:
public class User
{
public User(string uID)
{
this.UID = uID;
}
AccountInterface AccountInterface = new AccountInterface();
public string UID {get;private set;}
private string _Alias;
public string Alias
{
get
{
if (Alias.IsNullOrEmpty())
this._Alias = AccountInterface.GetAlias(this.UID);
return this._Alias;
}
set
{
if (this._Alias == value) return;
AccountInterface.UpdateAlias(this.UID,value);
this._Alias = value;
}
}
}
From my Understanding, each new instance of User will create a new instance of AccountInterface. Could this impose negative effects? Is this the proper way to handle multiple Instances?
I have had many simillar encounters in my projects and always ask myself if this is how things are done. For example, I have a program reading from a ticket system. After all I am able to modify/edit each instance of a ticket with someTicket.Description = "new Description" or someTicket.WriteComment("Some comment")
I wonder if it's better to build all logic into the interface class and work like
TicketInterface.WriteComment(someTicket, "Some Comment") or TicketInterface.ChangeDescription(someTicket, "some description").
I find the first Method more clean and intuitive as I can have general code in the Interface (Such as TicketInterface.GetAllTickets() ) while having instance specific code such as someTicket.WriteComment("Some comment") within the Instance. I believe this might cause negative impact, for example by opening a new Database Connection for each new Instance of an Object.
As AccountInterface is managing tasks which are not required to be bound to another class instance you could make AccountInterface a static class or implement the singleton pattern in an static context.
public static class AccountInterface{
public static WriteToFile(string output){...}
public static WriteToDb(object obj){...}
}
Or
public static class AccountContext{
private static AccountInterface _interface;
public static AccountInterface Interface {
get { return _interface; }
set
{
if(_interface == null) _interface = value;
}
}
From my Understanding, each new instance of User will create a new instance of AccountInterface. Could this impose negative effects? Is this the proper way to handle multiple Instances?
Maybe? It is perfectly reasonable for a object to instantiate other objects on constructions. One thing that seem odd is that AccountInterface does not take any parameters, in some cases this is perfectly fine, but in some cases it suggests that the class and the methods it contain should be 'static'.
If AccountInterface has any dependencies it might be better to use dependency injection. I.e.
public User(string uID, AccountInterface accountInterface)
{
this.UID = uID;
this.accountInterface = accountInterface;
}
AccountInterface AccountInterface;
And let a dependency injection framework take care of resolving any dependencies. If you have any static dependencies this can help avoid these, since it lets all components in the DI container share a object, instead of sharing the same object in the entire program.
In your ticket example, a typical design would use a ticket repository that is responsible for loading and saving tickets. Once a ticket has been loaded it can be modified using the properties and methods on the ticket, and once done it would be saved back to the repository. So GetAllTickets would be part of the repository class, but WriteComment would be part of the ticket class.
When accessing resources remotely it can be somewhat more common with a interface like TicketInterface.WriteComment(ticketId, comment) since that would be very easy to translate to a webrequest, and it can avoid downloading a somewhat large objects when you do not need all the data it contain.
Here is the conundrum. I have a specific set of state variables that are used in almost every supporting object I have, and I want those variables to be able to be read by any object that needs to read them, but I want to protect them so that only 1 object has the ability to set them.
For example, lets say I am making a poker game. Variables like:
- Minimum Ante
- Maximum Bet
- Maximum Number of Players
- Current GameState (Placing Bets, Shuffling, Dealing, Paying, etc.)
Personally, I prefer small compact component classes, so lets say I have the majority of the poker game logic in 1 controller class, but i have 50 supporting objects that handle everything that isn't the poker game logic itself, such as a PlayerInterface, a graphics controller, 'The Deck' to handle shuffle and deal logic, etc. Alot of my smaller support classes need to see what the minimum ante is, and the current method I am using is for the controller class to pass these variables into the supporting classes as parameters.
The obvious downside to this is I have 50 supporting objects all holding on to their own local variables for minimum ante to hold the same information that I am passing to them from the controller. Wasted parameters, memory, and opens a ton of risk if any of those variables ever get out of sync.
So, how to I make these variables global so everyone can access and read them? The knee jerk reactionary answer is some public static variables, however this presents the problem that anyone could also write to them. Not only do I not want my supporting objects having the power to change the minimum ante without the controller's knowledge, but I also don't want the client shell that holds the poker game to be able to change them without first going through the proper checks contained in the controller.
So what do I do? Someone once mentioned to me the idea of a Singleton, but after plenty of research, most of it a few years old or more, I found about a 50/50 split in the community who say Singletons are a good idea vs those who think they aren't.
If not singletons or statics, then what? I am open to any ideas to research and try out.
Remember, I want any object, anytime, anywhere to be able to GET the data it needs, but only a very specific object to have the ability to SET the data, should it need to change, so that it can filter through the proper checks. By proper checks, I mean for example in the poker game, if a player has the ability to change the Minimum Bet on the table, he should only be able to do so between hands, or before a tournament begins. I don't want him messing with these things during play.
Thanks in advance for any input.
You could use interfaces approach here.
Declare two interfaces as
public interface IReadOnlyAccess
{
int Property{get;}
}
public interface IFullAccess
{
int Property{get;set;}
}
Then your class would implement both interfaces like
public interface MyClass: IReadOnlyAccess, IFullAccess
{
public int Property{get;set;}
}
Then wherever you need full access you get it via IFullAccess, if otherwise - via IReadOnlyAccess.
Make an inner class, it will have access to the main classes private vars:
public class OuterClass
{
public string StringProperty { get; private set; }
public InnerClass CreateInnerClass()
{
InnerClass ic = new InnerClass(this);
return ic;
}
public class InnerClass
{
private OuterClass _outer;
public InnerClass(OuterClass oc)
{
_outer = oc;
}
public string Prop
{
get
{
return _outer.StringProperty ;
}
set
{
_outer.StringProperty = value;
}
}
}
}
So create the main class that most people have readonly access:
var oc = new OuterClass();
oc.StringProperty = "123"; <-- not allowed, is `readonly`
To write to properties, create inner class instance:
var oc = new OuterClass();
var ic = oc.CreateInnerClass();
ic.StringProperty = "123";
Seems like the cleanest, easiest solution is to have everything done in your controller class.
Let's say something like this:
AS3:
//adding the final keyword, locks this class so others can't extent/inherit from it
public final class MyController {
//create a privately scoped var (it can only be accessed in this class)
private var minBet:Number = 0;
//create a public getter that can be read by any class/object
public function get minimumBet():Number {
return minBet;
}
private function set minimumBet(value:Number):void {
//do you checks etc
minBet = value;
}
}
C#
//sealed in C# is the same as final in AS3
public sealed class MyController
{
private float minBet = 0;
public float minimumBet
{
get { return minBet; }
}
}
instanceOfMyController.minBet //will throw an error
instanceOfMyController.minimumBet = 10; //will throw an error
instanceOfMyController.minimumBet //will supply the value of the minBet var
If you're doing a lot cross-language code, consider checking out something like Haxe which can compile out to AS3 or C# with the same code.
I know that you can use session variables in web apps, I can't figure out how to use one in a desktop (windows forms and not a mobile android) one.
I have a Player class that is used to associate players with other classes in the app/SQLDb (they may or may not be the active user). But I want to have a CurrentPlayer (the person who actually has the application running) set.
In the Program class at start up, I'm running checks to see if the current user exists and if not, add them to the SQLdb. But at that time I'd like to set up an application-wide object for the user I've just added. In fact, if they're not in the db they can't run the app.
Obviously static doesn't work because I don't want to make the Player class static all the time. But I really do need to have this object set and the info easily available. EDIT: The reason it can't be static all the time is that in every other instance but the current user, I definitely want the creation of a player object to take place. I guess it's like the old Marine Corps thing. There are many players but this one is mine.
Yes, I know, global variables are not generally good, but here it makes sense (well I think so, if you all have other ideas I'm all ears), I just can't figure out how to implement it.
EDIT: I may not be being clear here. I guess I kind of need a singleton maybe? but I don't know in which file to declare the instance or how.
I have a MYAPPPlayer class that is used generally for many many instances, it can/should not be static (unless I want to be a crappy dev). But I need a MYAPPPlayer global singleton object variable for the current user of a non-web, desktop csharp app.
In your application you should have a static User CurrentUser property.
When you log into the application, set the Current User to the instance of that user.
If you are using WPF, I would make this a dependency property and have the rest of your application's interface bind to that property. If you are using forms, you'll have to manually handle the updating of all the UI when the user changes.
Edit: Short example of how something like this could be implemented with a static running program and a static INSTANCE of an object. I would also recommend you read more about what static means, and what a class is, it might be a bit more than you think... I'll explain a bit more at the bottom
class Program
{
static Player CurrentUser;
static void Main(string[] args)
{
string username;
bool isValidUser;
//get and validate user credentials
if (isValidUser)
CurrentUser = new Player(username);
SomeMethod();
}
static void SomeMethod()
{
if (CurrentUser == null)
return;
//do stuff with user
}
}
public class Player
{
public string Name { get; private set; }
//... more properties
public Player(string name)
{
Name = name;
//... more properties
}
}
Think about static vs non-static as such..... Non static classes are the blueprints for objects that you can construct and have multiple instances of. A static class is created when you have static members in a class. All the static members are separated out and a single instance of this static class is declared and referenced throughout your entire program whenever you reference one of those static members.... a better example of what I am saying is....
class Program
{
static Person John;
static void Main()
{
Console.WriteLine("Persons who exist {0}", Person.Total);
John = new Person("John");
John.Born();
John.Birthday();
Person Jane = new Person("Jane");
Jane.Born();
Console.WriteLine("Persons who exist {0}", Person.Total);
Console.WriteLine("John's Age {0}", John.Age);
Console.WriteLine("Jane's Age {0}", Jane.Age);
Console.ReadKey(true); //Pause program
}
}
class Person
{
public static int Total { get; private set; }
public static Person()
{
Total = 0;
}
public string Name {get; private set;}
public int Age { get; private set; }
public Person(string name)
{
Name = name;
Age = 0;
}
public void Born()
{
Total++;
}
public void Birthday()
{
Age++;
}
public void Death()
{
Total--;
}
}
As you can see above I have a static main method who has access to a John Person. The Person Class is non-static, however it does have a static member. Notice that the instances of Person internally can access the static variables, but from the main method you must say Person.Total to get the total. Also note that the static part of the Person class has no access to any of the instances of Person, but all instances of Person have access to the static members of Person, this is how they can iterate up the total amount of Persons when one is born, or iterate down when one dies.
The CurrentPlayer could be static since it's the current player.
internal class Data
{
public Player CurrentPlayer { get; set; }
.... // other variables
}
Usage: Data.CurrentPlayer = ResponseFromWebServiceCall.Player;
There's nothing wrong with having a static variable to represent the current player if there can be only one current player at a time.
Edit, to clarify: If there is only to be a SINGLE representation of an object, then using a static variable to hold that information is perfectly acceptable. In your classes, it's up to you if you want to reference that player variable as I have shown above with usage, or if you want to accept the player variable through a constructor parameter, for example. Actually, doing it that way would give you the best trade-off for portability.
I'm trying to model a production system with "facility" as Class and some subclasses down to "Activity". The facility has a name as only parameter (at the moment), and I'd like to create an instance of the class reading the name as an input from a textbox. Since "activity" is inherit the properties from it's "parent classes" I'll create an instance of the class "activity" and not it's parent.
The problem is that I don't know where to create the class and how to pass it so that when I add the first subclass "Workstation" I can edit the properties of the same "activity" I created earlier.
I don't really have any code to add at this point unfortunately, but please tell me if there's anything special you'd like to see and I'll try to add it to the post.
And by the way, it's in the shape of a WinForm application with a GUI I'm trying to do this.
There are a couple things to note here. First, you'll want to use the Composite pattern to encapsulate the relationships between your classes. (For those who don't understand the OP's type hierarchy, it does make perfect sense in a factory context. There are many activities going on, which can be grouped into workstations and at a higher level into facilities.)
So, you should probably have a base Activity class (that supports the Composite pattern by exposing a collection of child activities), and then your "levels" (like Facility and Workstation) will inherit from Activity. Each of these classes will have unique properties.
The following classes should be created in their respective files, e.g. Activity.cs, Factory.cs, Workstation.cs:
class Activity
{
// An attribute that every Activity may need: a displayable name.
// This might be useful if you have a TreeView, e.g., showing all the activities.
public string Name { get; private set; }
// Every Activity could have child activities - this is the Composite pattern.
// You can loop through these to navigate through the hierarchy of your data.
// (This is often done using recursion; see example below with GetAllWorkstations().)
public List<Activity> ChildActivities { get; private set; }
public Activity()
{
ChildActivities = new List<Activity>();
}
public override string ToString() { return Name; }
}
class Factory : Activity
{
public string City { get; private set; }
public string Address { get; private set; }
}
class Workstation : Activity
{
public string WorkstationNumber { get; private set; }
}
The responsibility of loading your model then has to be handled somewhere. A good place to do it is in your main form. For example, you might write code like this:
class MainForm : Form
{
private readonly List<Factory> topLevelFactoryActivities;
public MainForm()
{
// ... other code
topLevelFactoryActivities = LoadTopLevelFactoryActivities();
}
private IEnumerable<Factory> LoadTopLevelFactoryActivities()
{
var factories = new List<Factory>();
// TODO: Load the factories, e.g. from a database or a file.
// You can load all the child objects for each factory here as well,
// or wait until later ("lazy-loading") if you want to.
// NOTE: If this becomes complex, you can move the LoadTopLevelFactoryActivities()
// method to its own class, which then becomes your "data access layer" (DAL).
return factories;
}
}
Now, if you want to find all the workstations that are part of a particular factory, you would write a method like the following on the Factory class:
class Factory : Activity
{
// ... other code
public IEnumerable<Workstation> GetAllWorkstations()
{
return GetWorkstationsRecursive(this);
}
private IEnumerable<Workstation> WorkstationsIn(Activity parentActivity)
{
foreach (var workstation in parentActivity.ChildActivities.OfType<Workstation>)
{
// Uses a C# feature called 'iterators' - really powerful!
yield return workstation;
}
foreach (var childActivity in parentActivity.ChildActivities)
{
// Using recursion to go down the hierarchy
foreach (var workstation in WorkstationsIn(childActivity))
{
yield return workstation;
}
}
}
}
You would call it like so, e.g. in your main form:
class MainForm : Form
{
// ... other code
public MainForm()
{
// ... other code
// Assume this is assigned to the factory that you want to get all the workstations for
Factory myFactory;
var workstations = myFactory.GetAllWorkstations();
// Now you can use 'workstations' as the items source for a list, for example.
}
}
As an example use case, you might want to show a second form (that belongs to the main form) which shows a list of all the workstations. (In practice you probably shouldn't create too many windows; prefer building a nonoverlapping layout. But just to show how you might pass the model instances around...)
class WorkstationListForm : Form
{
private IEnumerable<Workstation> workstations;
public WorkstationListForm(IEnumerable<Workstation> workstations)
{
this.workstations = workstations;
//TODO: You can now use 'workstations' as the ItemsSource of a list view in this form.
}
}
You could, of course, make topLevelFactoryActivities public on your MainForm and pass the variable this of the MainForm to the WorkstationListForm constructor instead. Then you could access the member on MainForm like this:
public WorkstationListForm(MainForm mainForm)
{
var topLevelFactoryActivities = mainForm.topLevelFactoryActivities;
// Now WorkstationListForm has full access to all the data on MainForm. This may or
// may not be helpful (it's usually best to minimize sharing and public fields).
}
Second, you'll want to use a proper separation between your view (user interface code/classes) and your model (the Activity hierarchy).
Third, if there's going to be any kind of live data being pushed to the user interface then you'll need a databinding mechanism to automatically update the view whenever the model changes.
In general, #2 & #3 are popularly addressed via the Model-View-ViewModel pattern. There is an excellent tutorial here for building an MVVM app using WinForms/C#.
That should get you started, at least. Also see an answer to a similar question. (Sorry about promoting my own answer, but I don't want to type out the whole example twice. Please forgive me. :))
I'm learning C# and am trying to get my head around when to use classes and when not to.
If I was writing an app for a bank, I know I would use classes for customers which would include their name, account number, balance, etc. Would I use a static class for the methods that would deposit into their account, withdraw, change their address, etc since I only need to write them once?
Also, what would I use to keep track of every customer object? Having 2,000 Customers:
exampleName = new Customer();
in my code doesn't seem right. I'm not at the point of learning database's yet and am just learning classes.
Having a database would be ideal, but in the mean time you could use an IEnumerable to hold your Customer objects, like this:
List<Customer> myCustomers = new List<Customer>();
myCustomers.Add(new Customer {Name = "Bob", Address = "123 Anywhere St." });
Then you can just pass the list around where needed.
Typically you will then have a property on the Customer class that holds the accounts:
public class Customer
{
public Customer()
{
_accounts = new List<Account>();
}
public List<Account> Accounts
{
get { return _accounts; }
set { _accounts = value; }
}
private List<Account> _accounts;
}
And so on. Note that I'm keeping this simple and doing things the more long winded and descriptive way as you are a beginner.
Using lists of items in this way is a good way to start because you will natuarlly use these when you get to using a database; you will retrieve result sets from the database and then translate those result sets into lists of business objects.
As for using static methods to do business logic like adjusting balances, changing addresses, etc., for you at this stage it doesn't matter. If you are using tools like Resharper it will nag you with suggestions like that, but in your case you can safely ignore that particular one. What you should look for is keeping everything as self contained as possible, avoid leakage of data and leakage of responsibilities between objects - this is just good coding discipline and a good way to prevent bugs that are caused by loose coding.
Once you've got your functionality laid down and working, you may have a desire to move some functionality into static 'helper' style classes. This is absolutely fine, but do be careful - helper classes are fantastic and everything but can quickly turn into an anti-pattern if you don't maintain that coding discipline.
You don't need to use a static class, or static methods, in order to only write the methods once. It may or may not make sense to do so, but this is a perfectly valid way to write the methods without repeating yourself:
public class Customer
{
//properties, constructors, etc.
public virtual void Deposit(decimal amount) { }
public virtual void Withdraw(decimal amount) { }
//etc
}
This also allows you to make use of polymorphism, e.g.
public class BusinessCustomer : Customer
{
public override void Deposit(decimal amount) { //some other implementation }
}
Static classes are used when you aren't going to instantiate objects. You get one "instance" of that class - you can't do things like:
MyStaticClass m = new MyStaticClass();
m.SomeFunc();
when you've got a static class. Instead you'd use it by using the class name itself. Something like:
MyStaticClass.SomeFunc();
As to what would you use to keep track of every Customer object? You could use some sort of collection to hold these. Granted, in a real system there'd be some sort of persistence piece, likely a database, to hold the data. But you could just make something like:
IEnumerable<Customer> Customers = new List<Customer>();
And then add your customers to that list
Customers.Add(new Customer() { ... });
Back to the question about static methods...
So, the deal here is that you're not going to be referencing instance members in a static method, so you wouldn't use static methods to update a particular Customer's address. Assuming your Customer class looked like:
public class Customer
{
public string Address { get; set; }
}
You couldn't use a static method like
public static void SetAddress()
because each Customer (presumably) has a different address. You couldn't access the customer's address there because it isn't static. Get that? Instead, you'd use a static method if you were wanting to do something that didn't need to deal with instance data. I use static methods for things like utility functions.
public static double ComputeSomething(double someVal) { ... }
Here, the ComputeSomething function can be called by anybody like:
var result = MyStaticClass.ComputeSomething(3.15);
The takeaway here is that static classes aren't used to instantiate objects, rather they are used really as a convenient container to hold functions. Static functions are ones that can be on a non-static class but can't access any of the instance data.
One place where a static function would be used would be for the Singleton pattern. You make the constructor non-public so folks can't call it, and instead provide a static method on the class to return the one and only instance of the class. Something like:
public class MySingleton
{
private static MySingleton instance;
private MySingleton() {}
public static MySingleton Instance
{
get
{
if (instance == null)
{
instance = new MySingleton();
}
return instance;
}
}
}
what for withdrawls, deposits, etc
Those would be called Transactions.
This is meant to be in addition to the other answers. This is example of polymorphism with interfaces.
public interface IDeposit {
void Deposit(decimal amount);
}
public interface IWithdraw {
void Withdraw(decimal amount);
}
public class Customer : IDeposit, IWithdraw {
public void Deposit(decimal amount) { throw new NotImplementedException(); }
public void Withdraw(decimal amount) { throw new NotImplementedException(); }
}
public class DepositOnlyATM : IDeposit {
public void Deposit(decimal amount) { throw new NotImplementedException(); }
}
Keeps concepts separate, and allows for implementing multiple interfaces, or just one. With class inheritance approaches you only get one, and you get all of it. Inevitably you end up with spaghetti in my experience because sub-classes want some of the behavior, but not all of it.
I would recommend instead of getting into the implementation details right away that you first write down some simple user stories for your bank example. For instance
As a customer I would like to open a new account so that I can make deposits and withdrawls
Just in that requirement, we can envision a couple of classes (customer and account). From there just functionally decompose what the customer should do and what the account should do.
I've found that the book "The Object Oriented Thought Process" is a good read and will help answer some of the questions as to "when do I do this vs. that".
Good luck and have fun!