So, apologies in advance for the surely poor terminology in this question - I'm trying to teach myself C#, and struggling with a few concepts.
In pseudo-code, I have something like this:
static void Main()
{
// This will create lots of "Item"(s), and do stuff with them
}
public class Item
{
// a bunch of properties
public Item()
{
}
}
Next, I need a UtilityFunction1 that'll do some work - it will be called many times during Main() and passed Items to do some calculations with them. This function needs to set up a Dictionary to do its job. Even though it will be called many times, the Dictionary should only be set up once.
I also need a UtilityFunction2. Like UtilityFunction1, this function also needs a Dictionary to do it's job, which should only be set up once. This function will be called many times by UtilityFunction1.
So, on one hand, it seems like UtilityFunction1 and UtilityFunction2 should be public classes, since they need to have a constructor that populates the Dictionary (which involves variables, looping, and calculations).
On the other hand, I only need one of UtilityFunction1 and UtilityFunction2, so it seems like they should be static methods. But if that's the case, how/when do they do the work to set up the Dictionaries they need?
How do you achieve this?
You could also move your logic outside of Main.
What forces you to use static is that Main method (and class it's part of, usually) is static. That forces all other things (fields, methods, events, you name it) to also be static. The easiest way of curing that headache would be to create new class to hold all things you need.
Create new Logic class and put all things in it. The Item class stays the same. you can move it to separate file for clarity.
Logic.cs:
public class Logic() {
private Dictionary<object,object> dict1 = new Dictionary<object,object>
private Dictionary<object,object> dict2 = new Dictionary<object,object>
public Logic() {
// some logical initializations here
}
private void UtilityFunction1 (Item itemToWorkOn) {
// you can access dict1 directly from here
}
private void UtilityFunction2 (Item itemToWorkOn) {
// you can access dict2 directly from here
}
public void Run() {
// run UtilityFunction1() many times
// run UtilityFunction2() many times
}
}
Item.cs:
public class Item() {
// a bunch of properties
public Item() {}
}
And then just run it in your Main.
Program.cs:
static class Program {
static void Main() {
new Logic.Run();
}
}
Maybe you can think of the Singelton Design Pattern for your UtilityFunction*
https://msdn.microsoft.com/en-us/library/ff650316.aspx
You need a class that has only one instance, and you need to provide a global point of access to the instance.
You may use a static constructor. A static constructor is guaranteed to be executed just once for the class and before the class is used for the very first time. A static constructor is a very good place for initialization of static properties. It may look like:
public class ExampleClass
{
public static readonly IDictionary<int, Item> Items;
static ExampleClass()
{
Items = new Dictionary<int, Item>();
}
}
However, be careful with static stuff as it usually decreases the modularity and testability of a program. Therefore the use of a singleton pattern might be a better solution rather than a static constructor.
Related
Someone once wrote:
The space required for an instance depends only on the fields.
The methods require memory too but only one time per class. Like static fields. That memory is allocated when the class is loaded.
But what happens if a class with say like 5 methods and no fields get multiple instances in fields of other classes(composition).
Do they require more memory? Or would it be the same as static methods?
I do ask this question also because maybe it even gets optimised when compiling?
Is there a differents to static class with static methods? Other than u need to create the class each time or pass it around?
Eg.:
class Test1
{
public void DoThis()
{
...
}
public void DoThat()
{
...
}
}
class Test2
{
public void DoSomething()
{
...
}
private Test1 sample = new Test1();
}
class Test3
{
public void DoSomethingElse()
{
...
}
private Test1 sample = new Test1();
}
And so on...
"Behind the scenes", a class method is just like a static method, with the class instance beeing passes by reference as the first parameter.
That is, unless you use virtual methds, which "behind the scenes" are saved as instance members.
That is, because as long as you don't override a method, there is simply no reason to waste an instance's space.
Therefore, the size of both your class instances won't be affected by any non-virtual method you add to the class.
This concept can change between programming languages tho. For example, in Java and Python class methods are virtual by default.
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.
Problem Description
I'm trying to implement a very specific sort of cache of objects that I may not be able to instantiate directly (private constructors for instance)
What I want to do is read some information about the particular class, preferably through some kind of interface (which sadly doesn't support static methods defined for every subclass)
In other words:
public class Data
{
public static bool Attribute1() => False;
private Data(...) { ... }
}
public class Cache<T> // T is for instance Data
{
void SomeMethod()
{
bool Value = T.Attribute1()
...
}
}
It's fine if I can make T inherit from some base class or some interface, and to get the attribute through some sort of method or directly. It is very important though that I can
Program multiple data classes A and B, where A.Attribute1() is different from B.Attribute1()
Get the attribute from the data class type without instantiating the data type
Current Solution
I do currently have a solution in the shape of a registry built when the static objects are initialised, like this:
class CacheAttributesRegistry
{
static RegisterAttributes(Type T, bool Attribute1, ...) { ... }
}
class Data
{
static Data() { RegisterAttributes(typeof(Data), true, ...); }
}
class Cache<T>
{
void SomeMethod()
{
bool Value = CacheAttributesRegistry.Attribute1(typeof(T));
}
}
It does exactly what I want, but I'd prefer avoiding a static constructor in every data class, also I don't want it to be possible to accidentally call RegisterAttributes at runtime.
Preferably I'd also avoid reflection because I'd like it to be obvious how to set the attributes for a class without the code magically inferring it in the background.
Am I missing some option or have I just reached some language limitations?
I'm attempting to make a namespace for the first time while learning programming. I am hoping there is a way around the problem I've run into that isn't particularly messy, but essentially I have a class object that keeps two dictionaries of two nested class objects. I need to be able to pass the Dictionary of NestedClassA to NestedClassB or to allow NestedClassB to access it in some way... Here is an example of what I'm trying to do:
namespace MyFirstNamespace
{
public class BossClass
{
public Dictionary<int, NestedClassA> DictionaryA = new Dictionary<int, NestedClassA>();
public Dictionary<int, NestedClassB> DictionaryB = new Dictionary<int, NestedClassB>();
public class NestedClassA { ...arbitrary class definition... }
public class NestedClassB
{
public Dictionary<int, NestedClassA> PassedDictionary;
public NestedClassB() { }
public NestedClassB(Dictionary<int, NestedClassA> tempDic))
{
PassedDictionary = tempDic;
}
}
public BossClass() { ... arbitrary constructor ... }
...arbitrary dictionary population methods...
function void CreateAClassBInstance()
{
DictionaryB[n] = new NestedClassB(n, DictionaryA);
}
}
}
My problem seems to be that I can't typecast "NestedClassA" within "NestedClassB" because it doesn't recognize the type. Is it possible to access the "NestedClassA" type within B? Nothing I've tried has worked. Do I have to pass the instance of "BossClass" so I can reference type by "Dictionary<int, MyFirstNamespace.BossClassInstance.NestedClassA>"?
Any help would be appreciated. To be clear, I want a REFERENCE variable passed to NestedClassB of a Dictionary of all NestedClassA members so they can be manipulated by NestedClassB. It can't be a clone. I know this seems like ridiculous implementation, but it seems the most effective, if it's possible, for what I'm trying to do.
EDIT: maybe I shouldn't be nesting them at all, but it would make them much easier to serialize, which is why I really wanted to do it this way.
(EDIT - fixed typo where I forgot to insert "public" before constructors.)
There doesn't seem to be anything particularly wrong with your implementation of NestedClassB other than you need to make your constructors public if you wish to instantiate an instance of NestedClassB. By default in .Net, objects are passed by reference to function parameters, so you will have the same instance of Dictionary<int, NestedClassA> in NestedClassB.
Here is the adjusted class:
public class NestedClassB
{
private readonly Dictionary<int, NestedClassA> _PassedDictionary;
public NestedClassB() { }
public NestedClassB(Dictionary<int, NestedClassA> tempDic) {
_PassedDictionary = tempDic;
}
public Dictionary<int, NestedClassA> PassedDictionary {
get { return _PassedDictionary; }
}
}
Note that I changed PassedDictionary to a property instead of a member variable. Most serializers will ignore member variables and only serialize properties. If you need to deserialize, you'll need to remove the readonly from the private member variable and add a setter.
The function at the bottom of your code snippet doesn't look right. You'll want to make it look like:
private void CreateAClassBInstance()
{
DictionaryB[n] = new NestedClassB(DictionaryA);
}
For anyone trying to do this: passing the instance of the wrapper class is necessary for the nested class to access methods or variables of the wrapper class. This can be done with "this" keyword.
I am wondering which is a better way to store information? A central static class or in a parent class?
The code for the way I am storing it now. I instanciate a new class everytime.
Parent Class:
public partial class frmEmployeeManager: Form
{
List<Employee> lstEmployees = List<Employee>();
public frmEmployeeManager()
{
InitializeComponent();
}
public void updatePay(float Pay, int ID)
{
//Where ID = ID change the Pay
//(Omitted the foreach loop here for brevity)
}
private void btnDisplayData_Click(object sender, EventArgs e)
{
frmUpdatePay dlgUpdatePay = new frmUpdatePay(this);
dlgUpdatePay.ShowDialog();
}
}
Child Class:
public partial class frmUpdatePay : Form
{
private frmEmployeeManager ParentEmployeeManager;
public frmUpdatePay(frmEmployeeManager EmployeeManager)
{
InitializeComponent();
ParentEmployeeManager = EmployeeManager;
}
AddPersonParent.updatePay(fltPayInput, intID);
}
Taking a stab in the dark (since I don't know exactly what you are trying to accomplish), I would make an instantiated class and use a singleton pattern.
Personally I would (and do) use a central static class. Both choices break the OO principles, but at least the central static class approach doens't expose the inner workings of my forms to the outside.
I have gotten myself into trouble before when I used a static list that held the "state" of thing, and I found myself adding static functions to "clear" or "update" the list, etc. So I learned to only use static classes or lists or variables for things that are, well, static-- non-changing.
If you are keeping objects in the list that can change, I would go the instantiated route.
Updated
Now that I see your list is an employee list, converting it to a static basically makes it's a global variable. Global variables are not good. I found this answer which summarizes it pretty well.