i have one class with constractor like this
public class product_new : NK.Objects._product_new
{
private int Count_Per_Page;
public product_new(int count_per_page)
{
this.Count_Per_Page = count_per_page;
}
public int CountOP///////count of pages
{
get
{
return number_of_pages(Count_Per_Page);
}
}
as you see the CountOP is return a int value and it is connect to sql database to return this value.
private int number_of_pages(int tedad_per_pages)
{
return Q.Get_Back_Number_Of_Pages(
tedad_per_pages,
tbl_name,
"",
new Queries.Cmd_Parameters());
}
in several time if create object from this class the CountOP is not changed but the function number_of_pages is released and connect to the sql database.
how can i cache this variable?
Try using static Dictionary<int, int> - one dictionary for all the instances:
public class product_new : NK.Objects._product_new {
// Simplest, but not thread safe; use ConcurrentDictionary for thread safe version
private static Dictionary<int, int> s_KnownAnswers = new Dictionary<int, int>();
// Lazy: do not execute expensive operation eagerly: in the constructor;
// but lazyly: in the property where we have to perform it
public int CountOP {
get {
int result = 0;
// do we know the answer? If yes, then just return it
if (s_KnownAnswers.TryGetValue(Count_Per_Page, out result))
return result;
// if no, ask RDMBS
result = number_of_pages(Count_Per_Page);
// and store the result as known answer
s_KnownAnswers.Add(Count_Per_Page, result);
return result;
}
}
...
}
Introduce a private backing-field that holds the value and initialize its value within your constructor. Now you can return the variables value within your getter instead of hitting the database every time you call the getter.
public class product_new : NK.Objects._product_new
{
private int Count_Per_Page;
private readonly int _CountOP;
public product_new(int count_per_page)
{
this.Count_Per_Page = count_per_page;
this._CountOP = number_of_pages(count_per_page);
}
public int CountOP///////count of pages
{
get
{
return this._CountOP;
}
}
Apart from this I strongly suggest to have a look at Mircrsofts naming-conventions.
Change to use a backed property:
private int _npages = -1;
public int CountOP///////count of pages
{
get
{
if(_npages == -1)
_npages = number_of_pages(Count_Per_Page);
return _npages;
}
}
Related
I am trying to create a custom dictionary with some methods. I created a struct containing the information for lanes in my game. One information tells me if there is an enemy in the lane(Occupied) and the other if we completed that lane so no more enemies will come there(Completed).
I am able to get the initial information out, but cannot update them with my methods. I construct it by adding all 7 lanes, where none of them are either occupied or completed. Then throughout my game, I would like to mark them either as completed or occupied or free, but even after a lot of time searching around, I couldn't figure out the proper way to call for an update of these items inside my laneInfo property.
public struct laneInfo
{
public bool Occupied;
public bool Completed;
}
public class laneInfoClass : Dictionary<int, laneInfo>
{
public laneInfo laneinfo;
public laneInfoClass()
{
for(int i = 0; i <= 6; i++)
{
this.Add(i, false, false);
}
}
public void Add(int key, bool occupied, bool completed)
{
laneinfo.Occupied = occupied;
laneinfo.Completed = completed;
this.Add(key, laneinfo);
}
public void Complete()
{
laneinfo.Completed = true;
}
public void Occupy()
{
laneinfo.Occupied = true;
}
public void Free()
{
laneinfo.Occupied = false;
}
}
Thanks!
Its fairly rare that your class would inherit from a dictionary/list/collection (why?), more often than not what you are actually modelling is a class which has an instance member which is that same dictionary/list/collection.
In addition, you need some way to notify your class which particular lane you're trying to update, you use an integer key so work with that:
public struct LaneInfo
{
public bool Occupied {get;set;}
public bool Completed {get;set;}
}
public class LaneInfoContainer
{
private Dictionary<int, LaneInfo> laneInfoDict = new Dictionary<int, LaneInfo>();
public LaneInfoContainer()
{
for(int i = 0; i <= 6; i++)
{
this.Add(i, false, false);
}
}
public void Add(int key, bool occupied, bool completed)
{
var laneInfo = new LaneInfo();
laneinfo.Occupied = occupied;
laneinfo.Completed = completed;
this.laneInfoDict.Add(key, laneinfo);
}
public void Complete(int key)
{
laneInfoDict[key].Completed = true;
}
public void Occupy(int key)
{
laneInfoDict[key].Occupied = true;
}
public void Free(int key)
{
laneInfoDict[key].Occupied = false;
}
}
I suspect you might also need some way to read the info about your lanes too, add methods such as
public bool IsComplete(int key)
{
return laneInfoDict[key].Complete;
}
The answer to your question is that you should not use a Dictionary. Iterating a List<T>.Contains is faster than Dictionary<TKey, TValye> lookup for 7 items, especially if you are accessing them by index integer 0-6.
Part from that, Dictionary<TKey, TValue> is already generic and so there is no need to inherit from it. Sometimes you would wrap it, for various reasons (one might be locking). But if it is just for a few methods you can simply add extension methods to the Dictionary<int, LaneInfo>.
public static class LaneExtensionMethods
{
public static bool IsComplete(this Dictionary<int, LaneInfo> dictionary, int key)
{
return dictionary[key].Complete;
}
}
// Use
var d = new Dictionary<int, LaneInfo>();
var isComplete = d.IsComplete(1);
I often replace the int with a type to avoid bugs and confusion in code. This would in your case also allow for specialized extension methods. Casting has zero CPU cost (its just cosmetics in code).
public enum LaneId : Int32 { }
public static class LaneExtensionMethods
{
public static bool IsComplete(this Dictionary<LaneId, LaneInfo> dictionary, LaneId key)
{
return dictionary[key].Complete;
}
}
// Use
var d = new Dictionary<LaneId, LaneInfo>();
var laneId = (LaneId)1; // We cast from integer to LaneId, but use LaneId type everywhere in our app
var isComplete = d.IsComplete(laneId);
I have two constructors which feed values to readonly fields.
public class Sample
{
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
_intField = i;
}
public Sample(int theInt) => _intField = theInt;
public int IntProperty => _intField;
private readonly int _intField;
}
One constructor receives the values directly, and the other does some calculation and obtains the values, then sets the fields.
Now here's the catch:
I don't want to duplicate the
setting code. In this case, just one
field is set but of course there may
well be more than one.
To make the fields readonly, I need
to set them from the constructor, so
I can't "extract" the shared code to
a utility function.
I don't know how to call one
constructor from another.
Any ideas?
Like this:
public Sample(string str) : this(int.Parse(str)) { }
If what you want can't be achieved satisfactorily without having the initialization in its own method (e.g. because you want to do too much before the initialization code, or wrap it in a try-finally, or whatever) you can have any or all constructors pass the readonly variables by reference to an initialization routine, which will then be able to manipulate them at will.
public class Sample
{
private readonly int _intField;
public int IntProperty => _intField;
private void setupStuff(ref int intField, int newValue) => intField = newValue;
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
setupStuff(ref _intField,i);
}
public Sample(int theInt) => setupStuff(ref _intField, theInt);
}
Before the body of the constructor, use either:
: base (parameters)
: this (parameters)
Example:
public class People: User
{
public People (int EmpID) : base (EmpID)
{
// Add more statements here.
}
}
I am improving upon supercat's answer. I guess the following can also be done:
class Sample
{
private readonly int _intField;
public int IntProperty
{
get { return _intField; }
}
void setupStuff(ref int intField, int newValue)
{
//Do some stuff here based upon the necessary initialized variables.
intField = newValue;
}
public Sample(string theIntAsString, bool? doStuff = true)
{
//Initialization of some necessary variables.
//==========================================
int i = int.Parse(theIntAsString);
// ................
// .......................
//==========================================
if (!doStuff.HasValue || doStuff.Value == true)
setupStuff(ref _intField,i);
}
public Sample(int theInt): this(theInt, false) //"false" param to avoid setupStuff() being called two times
{
setupStuff(ref _intField, theInt);
}
}
Here is an example that calls another constructor, then checks on the property it has set.
public SomeClass(int i)
{
I = i;
}
public SomeClass(SomeOtherClass soc)
: this(soc.J)
{
if (I==0)
{
I = DoSomethingHere();
}
}
Yeah, you can call other method before of the call base or this!
public class MyException : Exception
{
public MyException(int number) : base(ConvertToString(number))
{
}
private static string ConvertToString(int number)
{
return number.toString()
}
}
Constructor chaining i.e you can use "Base" for Is a relationship and "This" you can use for same class, when you want call multiple Constructor in single call.
class BaseClass
{
public BaseClass():this(10)
{
}
public BaseClass(int val)
{
}
}
class Program
{
static void Main(string[] args)
{
new BaseClass();
ReadLine();
}
}
When you inherit a class from a base class, you can invoke the base class constructor by instantiating the derived class
class sample
{
public int x;
public sample(int value)
{
x = value;
}
}
class der : sample
{
public int a;
public int b;
public der(int value1,int value2) : base(50)
{
a = value1;
b = value2;
}
}
class run
{
public static void Main(string[] args)
{
der obj = new der(10,20);
System.Console.WriteLine(obj.x);
System.Console.WriteLine(obj.a);
System.Console.WriteLine(obj.b);
}
}
Output of the sample program is
50 10 20
You can also use this keyword to invoke a constructor from another constructor
class sample
{
public int x;
public sample(int value)
{
x = value;
}
public sample(sample obj) : this(obj.x)
{
}
}
class run
{
public static void Main(string[] args)
{
sample s = new sample(20);
sample ss = new sample(s);
System.Console.WriteLine(ss.x);
}
}
The output of this sample program is
20
Error handling and making your code reusable is key. I added string to int validation and it is possible to add other types if needed. Solving this problem with a more reusable solution could be this:
public class Sample
{
public Sample(object inputToInt)
{
_intField = objectToInt(inputToInt);
}
public int IntProperty => _intField;
private readonly int _intField;
}
public static int objectToInt(object inputToInt)
{
switch (inputToInt)
{
case int inputInt:
return inputInt;
break;
case string inputString:
if (!int.TryParse(inputString, out int parsedInt))
{
throw new InvalidParameterException($"The input {inputString} could not be parsed to int");
}
return parsedInt;
default:
throw new InvalidParameterException($"Constructor do not support {inputToInt.GetType().Name}");
break;
}
}
Please, please, and pretty please do not try this at home, or work, or anywhere really.
This is a way solve to a very very specific problem, and I hope you will not have that.
I'm posting this since it is technically an answer, and another perspective to look at it.
I repeat, do not use it under any condition. Code is to run with LINQPad.
void Main()
{
(new A(1)).Dump();
(new B(2, -1)).Dump();
var b2 = new B(2, -1);
b2.Increment();
b2.Dump();
}
class A
{
public readonly int I = 0;
public A(int i)
{
I = i;
}
}
class B: A
{
public int J;
public B(int i, int j): base(i)
{
J = j;
}
public B(int i, bool wtf): base(i)
{
}
public void Increment()
{
int i = I + 1;
var t = typeof(B).BaseType;
var ctor = t.GetConstructors().First();
ctor.Invoke(this, new object[] { i });
}
}
Since constructor is a method, you can call it with reflection. Now you either think with portals, or visualize a picture of a can of worms. sorry about this.
In my case, I had a main constructor that used an OracleDataReader as an argument, but I wanted to use different query to create the instance:
I had this code:
public Subscriber(OracleDataReader contractReader)
{
this.contract = Convert.ToString(contractReader["contract"]);
this.customerGroup = Convert.ToString(contractReader["customerGroup"]);
this.subGroup = Convert.ToString(contractReader["customerSubGroup"]);
this.pricingPlan= Convert.ToString(contractReader["pricingPlan"]);
this.items = new Dictionary<string, Member>();
this.status = 0;
}
So I created the following constructor:
public Subscriber(string contract, string customerGroup) : this(getSubReader(contract, customerGroup))
{ }
and this method:
private static OracleDataReader getSubReader(string contract, string customerGroup)
{
cmdSubscriber.Parameters[":contract"].Value = contract + "%";
cmdSubscriber.Parameters[":customerGroup"].Value = customerGroup+ "%";
return cmdSubscriber.ExecuteReader();
}
notes: a statically defined cmdSubscriber is defined elsewhere in the code; My main constructor has been simplified for this illustration.
In case you need to run something before calling another constructor not after.
public class Sample
{
static int preprocess(string theIntAsString)
{
return preprocess(int.Parse(theIntAsString));
}
static int preprocess(int theIntNeedRounding)
{
return theIntNeedRounding/100;
}
public Sample(string theIntAsString)
{
_intField = preprocess(theIntAsString)
}
public Sample(int theIntNeedRounding)
{
_intField = preprocess(theIntNeedRounding)
}
public int IntProperty => _intField;
private readonly int _intField;
}
And ValueTuple can be very helpful if you need to set more than one field.
NOTE: most of the solutions above does not work for structs.
Unfortunately initializing struct fields in a method called by a constructor is not recognized by the compiler and will lead to 2 errors:
in the constructor: Field xxxx must be fully assigned...
in the method, if you have readonly fields: a read-only field cannot be assigned except in a constructor.
These can be really frustrating for example when you just need to do simple check to decide on which constructor to orient your call to.
I have a class where I hold some variables :
public class PreviousCalls
{
private static int bot1Call;
public static int previousBot1Call
{
get { return bot1Call; }
set { bot1Call = value; }
}
private static int bot2Call;
public static int previousBot2Call
{
get { return bot2Call; }
set { bot2Call = value; }
}
private static int bot3Call;
public static int previousBot3Call
{
get { return bot3Call; }
set { bot3Call = value; }
}
private static int bot4Call;
public static int previousBot4Call
{
get { return bot4Call; }
set { bot4Call = value; }
}
private static int bot5Call;
public static int previousBot5Call
{
get { return bot5Call; }
set { bot5Call = value; }
}
}
I need to pass those variables as parameters to a lot of methods in my other class here's how I do it :
void AI(... , int previous)
AI(... , PreviousCalls.previousBot1Call);
So the parameter previous is changing the way it should but the variables from class PreviousCalls are not changing at all, why is that ?
int is value type, so there is a copy of 'previous value' passed to method body. So changing a variable inside method doesn't cause the original value change:
public void Test(int a)
{
a = 10;
}
int t = 11;
Test(t);
//t is still 11, because Test method operates on copy of t
To change original value you must use ref or out:
void AI(..., ref int previous) { ... }
int param;
AI(..., ref param); //when ref is used, original variable wil be changed.
PreviousCalls.previousBot1Call = param;
Unfortunately, you cannot use it like this:
AI(... , ref PreviousCalls.previousBot1Call); // compile-time error
// member-access is forbidden wtih out/ref
AI(,.., ref 10); // compile-time error
Another attempt:
interface IAIParam
{
int Previous { get; set; }
// other params
}
void AI(IAIParam p)
{
p.Previous += 1;
//....
}
And then implementaiton:
internal class MyBotProxy : IAIParam
{
public int Previous
{
get { return PreviousCalls.previousBot1Call; }
set { PreviousCalls.previousBot1Call = value; }
}
}
usage:
var myProxy = new MyBotProxy();
AI(myProxy);
Most commonly methods do not change any values outside of their method scope, instead they return a new value. Only methods that accept the parameter by reference instead of value can change the value of the parameter in the calling context.
This article on MSDN is a great starting point for understanding how to pass parameters by reference instead of value.
Please note that you will not be able to pass a class member as a ref or out parameter. If you wish to update part of a class via reference, you will need to pass the entire class object as the reference.
Please consider the following code
public class DataModel
{
public int a { get; set; }
}
public static class StaticAccess
{
private static _Data = new DataModel();
private static DataModel Data {
lock(_Data) {
return _Data;
}
}
}
Will an access to property a such us StaticAccess.Data.a = 3; will lock for the entire property value assignment or just for the _Data static field reference retrieval?
In other words, can I use the above implementation to synchronize the access to the properties of the underlying data model or do I have to implement the lock in every single property of it?
e.g.
public class DataModel
{
private int _a;
public int a {
get {
lock(this) {
return _a;
}
}
set {
lock(this) {
_a = value;
}
}
}
Thanks in advance.
The code in your first example will synchronize access to the instance of DataModel in the StaticAccess class (i.e.: to the _Data field), not to members of the instance of DataModel itself. For that you need your second example.
Side note: Avoid locking on this, and use a dedicated object to lock on, as you don't know who else might lock on the instance. Use something like
public class DataModel
{
private readonly object _lock= new object();
private int _a;
public int a {
get {
lock(_lock) {
return _a;
}
}
set {
lock(_lock) {
_a = value;
}
}
}
Edit based on comments:
The Data property of StaticAccess returns the instance of DataModel. So only thread at a time can obtain the reference to that instance. The goal, however, is to synchronize access to DataModel.a. Since access to DataModel.a is not synchronized any code that tries to either read or write to DataModel.a is not synchronized meaning that multiple threads accessing StaticAccess.Data.a is not synchronized:
void ThreadProc1()
{
// (might) block on "get StaticAccess.Data"
// will not block on "DataModel.a = 20"
StaticAccess.Data.a = 20;
}
void ThreadProc2()
{
// (might) block on "StaticAccess.Data"
// will not block on "DataModel.a = 10"
StaticAccess.Data.a = 10;
// (might) block on "StaticAccess.Data"
// will not block on "DataModel.a"
// "StaticAccess.Data.a" might be 10 or 20;
Console.WriteLine(StaticAccess.Data.a);
}
I have the following class with a nested private class and I would like to assign the value of NID to Context. I have used getters and setters however the value of NID (Sequencer.Context = value;) never gets assigned to ( SeqNode = Node.LoadNode(Context); ). What am I doing wrong?
//Instantiation
Increment.NID = "/Root/Dir/NodetoIncrement";
String getSequence = Convert.ToString(Increment.SID);
// The Class
public static class Increment
{
//Value of the node Context location in the tree to increment ( Increment.NID )
public static string NID
{
set { Sequencer.Context = value; } //The "/Root/Dir/NodetoIncrement";
}
//Get the sequence ID
public static int SID
{
get { return Sequencer.GetSeqId; }
}
//Nested sequencer class. This increments the node.
private class Sequencer
{
private Node SeqNode;
private static int SequenceNumber;
private volatile bool Run = true;
public static string Context { get; set; } //gets
public static int GetSeqId
{
get
{
return Interlocked.Add(ref SequenceNumber, 1);
}
}
public Sequencer() //Constructor Here!
{
SeqNode = Node.LoadNode(Context);
SequenceNumber = Convert.ToInt16(SeqNode["LastSequenceNo"]);
//NEVER DO THIS .. causes the system to lockup see comments.
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
while (Run)
{
Save();
Thread.Sleep(5000);
}
});
}
private void Save()
{
//optimistic concurrency recommended!!
var retryMaxCount = 3; // maximum number of attempts
var cycles = 0; // current attempt
Exception exception = null; // inner exception storage
while (cycles++ < retryMaxCount) // cycle control
{
try
{
SeqNode["LastSequenceNo"] = Convert.ToString(SequenceNumber);
SeqNode.Save();
// successful save, exit loop
exception = null;
break;
}
catch (NodeIsOutOfDateException e)
{
exception = e; // storing the exception temporarily
SeqNode = Node.LoadNode(Context);
}
}
// rethrow if needed
if (exception != null)
throw new ApplicationException("Node is out of date after 3 attempts.", exception);
}
~Sequencer() { Save(); }
}
}
public class XYHandler : Node
{
public override void Save(NodeSaveSettings settings)
{
base.Name = Convert.ToString(Increment.SID);
base.Save();
}
public override bool IsContentType
{
get { return true; }
}
}
What am I doing wrong?
You are waiting for another thread in a static initializer. NEVER DO THAT. I can't emphasize strongly enough how insanely dangerous that is.
For an explanation why, see this answer:
https://stackoverflow.com/a/8883117/88656
Is there some temporal coupling at play here?
SeqNode is set when the Sequencer is instantiated, but I can't see an instantiation in your sample.
The static constructor will run before the property setter is invoked the first time, and then try again 5s later - when is the property being set?
I can't see where Sequencer is being constructed (perhaps I missed it). Since it isn't a static constructor it will have to be called at least once for LoadNode to run. Did you intent to make that constructor static also?