I'm working on an object in C# where I need each instance of the object to have a unique id. My solution to this was simply to place a member variable I call idCount in the class and within the constructor I would have:
objectID = idCount;
idCount++;
I thought that this would solve my problem but it seems that idCount never gets incremented even though the constructor gets called multiple times. For example if idCount = 1, the objectID for all the objects are still 1. Why doesn't idCount++ work?
Any help would be appreciated. Apologies if my explanation isn't adequate, I'm not sure how else to explain it.
You need a static property in your class, BUT, you need to assign it to an instance variable within the class if you want each object to contain the id it was created with.
Also, you'll want to use Interlocked.Increment on the counter in case you are updating multiple instances simultaneously:
public class Foo
{
private static int m_Counter = 0;
public int Id { get; set; }
public Foo()
{
this.Id = System.Threading.Interlocked.Increment(ref m_Counter);
}
}
You could use a static variable in your class that gets updated when the object is initialized.
public class Foo
{
private static int ID = 0;
private int myId = 0;
public int MyId
{
get { return myId; }
}
public Foo()
{
ID++;
this.myId = ID;
}
}
As everyone has pointed out, static variables are the specific answer to your question. But static variables only have scope within the process in which they were created and there is no relationship across processes (for example, a load balanced web environment).
If what you are looking for is a unique way to identify an object instance for the duration of its lifetime, I suggest something like:
byte[] bytes = new byte[8];
RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();
crypto .GetBytes( bytes );
long id = BitConverter.ToInt64( bytes, 0 );
This will give you a random number which has an extremely low (roughly 0-1 in 100,000,000) chance of collision and you don't need to worry about keeping track of it.
You set IdCount is static member of MyObject.
public class MyObject
{
static int idCount = 0;
private int _objectID;
public int ObjectID
{
get { return _objectID; }
}
public MyObject()
{
idCount++;
_objectID = idCount;
}
}
public sealed class SingletonIdGenerator
{
private static long _id;
private SingletonIdGenerator()
{
}
public string Id
{
get { return _id++.ToString().Substring(8); }
}
public static SingletonIdGenerator Instance { get { return Nested.instance; } }
private class Nested
{
static Nested()
{
_id = DateTime.Now.Ticks;
}
internal static readonly SingletonIdGenerator instance = new SingletonIdGenerator();
}
}
Related
public int userID;
//global variable
public Index()
{
userID = 10;
return userID;
}
public TaskCompleted()
{
Console.WriteLine(Index())
}
i want the userID to be accessed in each and every method and can we updated anywhere
Your Index method has two problems.
Syntax problem: Every method must have a return type. Either a real type like int or the void keyword.
public int Index()
Semantic problem. At every call it sets userID and returns it. Why store the value in this variable? It will be replaced by a new value at the next call and could just be a local variable (i.e., a variable inside the method) or be dismissed completely. But maybe your example was simply not complete.
Let's try different approaches:
Passing value through a class field (your "global" variable).
private int _userId;
public void SetUserId() // `void` means that the method is not returning a value.
{
_userId = 10;
}
public void PrintUserId()
{
Console.WriteLine(_userId);
}
This requires you to call SetUserId(); before calling PrintUserId();
Let the method return the value.
public int GetUserId() // `int` means that the method is returning an `int` value
{
return 10;
}
public void PrintUserId()
{
Console.WriteLine(GetUserId());
}
Combine the two previous approaches
private int _userId;
public void SetUserId()
{
_userId = 10;
}
public int GetUserId()
{
return _userId;
}
public void PrintUserId()
{
Console.WriteLine(GetUserId());
}
C# has a concept called "property". A property is a set of "Get" and "Set" methods, just as in the previous example, but with as special syntax.
private int _userId;
public UserId
{
get { return _userId; }
set { _userId = value; }
}
public void PrintUserId()
{
Console.WriteLine(UserId);
}
A property having no additional logic besides assigning and returning a value can also be implemented as an auto-property.
public int UserId { get; set; } // A hidden field is automatically created.
The caller would have to do something like this:
var obj = new MyClass();
obj.UserId = 10;
obj.PrintUserId();
You can use a static property of a static class:
public static class Globals
{
public static int UserID {get; set;}
}
Usage: var userId = Globals.UserID;
I am learning C# so I am still on the basics here. This is my code
class foo
{
protected int id;
protected string data;
static int nextId = 1;
public int Id
{
get { return id; }
}
public foo()
{
this.id = nextId++;
}
public foo(string somedata)
{
this.data = somedata;
this.id = nextId++;
}
}
This code works just fine for now. All objects will have a unique ID with them.
Problem is: I don't want the first ID to be 1, I want it to be the number on the first line of the file given as an argument to the application from the commandline. If no file is specified or the file does not exist, then it can be one. Is there a way to make a one-time method to set nextId so it cannot be tampered with outside of the class after it has been once set?
Duh... I guess this is the trick. Still, I'd like to know if there is some build in way to make variables that can only be set once.
public int nextId
{
set {if(nextId<1) nextId = value;}
}
You can implement static constructor, which assigns proper value to nextId before first usage of foo class:
using System.IO;
using System.Linq;
...
class foo
{
...
static int nextId;
// read-only property which however can be assigned in the constructor
public int Id {get;}
// This static costructor will be called once before 1st usage of foo class
static foo() {
//TODO: put the right file name here
string fileName = Environment.GetCommandLineArgs()[1];
nextId = int.Parse(File
.ReadLines(fileName)
.First());
}
public foo()
{
//Let's increment nextId in thread-safe manner
Id = Interlocked.Increment(ref nextId);
}
...
}
You can do this
class foo
{
private static int nextId = 1;
private static bool isNextIdSet;
public SetId(newId)
{
if (!isNextIdSet) nextId = newId;
isNextIdSet = true;
}
}
So the nextId can be set only once from outside the class.
UPDATE: if you prefer to use this with many variables, you can create a helper for this, such as
class SetOnlyOnce<T>
{
private bool isSet;
public T Value
{
get;
set
{
if (!isSet) Value = value;
isSet = true;
}
}
}
Then use it as
class Foo
{
public SetOnlyOnce<int> prop1 {get;set;}
public SetOnlyOnce<string> prop2 {get;set;}
}
class Bar
{
public Bar()
{
var foo = new Foo();
foo.prop1.Value = 2;
foo.prop1.Value = 3; // this doesn't set.
}
}
As an alternative to Dmitry's answer, you can define the initialization through a static method. I prefer avoiding static constructors unless multiple fields need to be initialized simultaneously.
using System.IO;
using System.Linq;
...
class foo
{
...
// The initialization will be called at some time before first use of nextId.
private static int nextId = GenerateInitialNextId();
// read-only property which however can be assigned in the constructor
public int Id {get;}
private static int GenerateInitialNextId() {
//TODO: put the right file name here
string fileName = Environment.GetCommandLineArgs()[1];
return int.Parse(File
.ReadLines(fileName)
.First());
}
public foo()
{
//Let's increment nextId is thread-safe manner
Id = Interlocked.Increment(ref nextId);
}
...
}
I'm trying to implement behavior similar to that of the GameObject in Unity3D.
I have many, many objects in any given application that reference any given number of other objects. Each object can be marked for deletion, and when it is; I need to know how to nullify any references to it so that it can be collected by the GC and literally removed from scope altogether. I'm either looking for a way to fake this or a way of actually doing it.
For all intents and purposes; if an object references another, and the referenced object is destroyed, I need the reference to appear to be null. If I can't do this then my only other option is to check every reference, every time I use them, and manually evaluate whether it's been destroyed, which isn't practical.
There are two approaches that I know of which come close to what you described:
Approach 1: WeakReference
Only use WeakReference to reference to objects except for one 'DataManager' that retains a hard reference.
You can then 'mark' instances for garbage collection by clearing the hard reference of the DataManager.
public class DataManager
{
private readonly HashSet<object> data = new HashSet<object>();
public void RegisterInstance(object instance)
{
data.Add(instance);
}
public void FreeInstance(object instance)
{
data.Remove(instance)
}
}
public class Foo
{
List<WeakReference<Bar>> bars = new List<WeakReference<Bar>>();
private readonly DataManager dataManager;
public Foo(DataManager dataManager)
{
this.dataManager = dataManager;
}
public void LogSomething()
{
bars.Add( Bar.Create(dataManager, 3, "Susan"));
bars.Add( Bar.Create(dataManager, 4, "Bob"));
bars.Add( Bar.Create(dataManager, 0, "Megan"));
dataManager.FreeInstance(bars[1]);
CG.Collect();
for(int i = bars.Count - 1; i >= 0; i--;)
{
// hard reference to not loose the reference target between now and logging
Bar bar;
if(!bars[i].TryGetTarget(out bar)
{
bars.RemoveAt(i);
continue;
}
Debug.Log($"{bar.value.Data2} has {bar.value.Data1} chocolate bars");
}
}
}
public class Bar
{
public int Data1 { get; private set; }
public string Data2 { get; private set; }
private Bar(int data1, string data2)
{
Data1 = data1;
Data2 = data2;
}
public static WeakReference<Bar> Create(DataManager dataManager, int data1, string data2)
{
var bar = new Bar(data1, data2);
dataManager.RegisterInstance(bar);
return new WeakReference(bar);
}
}
Cons
Weak references will continue to point to the target that was marked for deletion until it is actually garbage collected.
Running the garbage collector after each deletion isn't a very good idea
It's slow
Garbage collector might not even collect it. Meaning that a WeakReference can suddenly lose reference between two lines of code some time after deletion. This requires you to keep a hard reference everytime that you have to access the target of a weak reference more than just once.
You have to register every created object in the DataManager.
It's very easy to forget to use WeakReference to reference to objects.
Approach 2: Use a wrapper
You can wrap all your objects in a generic class and only reference the wrapper, but you have to use the same wrapper for every object of T.
So you will need some kind of DataManager like in approach 1.
public class Wrapper<T>
{
public T Value { get; private set; }
public Wrapper(T value)
{
Value = value;
}
public void Delete()
{
if(Value == null)
throw new InvalidOperationException("Already deleted");
Value = null;
}
public static implicit operator T(Wrapper<T> wrapper) => wrapper.value;
public static implicit operator Wrapper<T>(T x) => new Wrapper(x);
}
public class Foo
{
List<Wrapper<Bar>> bars = new List<Wrapper<Bar>>();
public void LogSomething()
{
bars.Add( new Bar(3, "Susan"));
bars.Add( new Bar(4, "Bob"));
bars.Add( new Bar(0, "Megan"));
bars[1].Delete()
for(int i = bars.Count - 1; i >= 0; i--;)
{
var bar = bars[i];
if(bar.value == null)
{
bars.RemoveAt(i);
continue;
}
Debug.Log($"{bar.value.Data2} has {bar.value.Data1} chocolate bars");
}
}
}
public class Bar
{
public int Data1 { get; private set; }
public string Data2 { get; private set; }
public Bar(int data1, string data2)
{
Data1 = data1;
Data2 = data2;
}
}
You could also overwrite the equals method of Wrapper to achieve the following behavior:
var bar = new Wrapper<Bar>(null);
var isWrappedValueNull = bar == null;
// overwrite 'equals' if you want isWrappedValueNull to be true in this case
I wrote this with the android app - example code might have minor errors
You can't set this (aka 'yourself') to null so that references to you will be lost / destroyed. this is read-only.
Something you can do is using events to tell the ones referencing the instance to set it to null. Don't forget to unsubscribe the event handler when setting the instance to null.
I don't know if the title is clear but basically I am trying to implement something like this:
public class Effect
{
public int InternalId ...
public void ResetName() ...
}
When ResetName is called, this will reset the name of the object to:
"Effect " + someIndex;
So if I have 5 instances of Effect, they will be renamed to:
"Effect 1"
"Effect 2"
"Effect 3"
...
So I have another method (ResetNames) in another manager/container type that calls ResetName for each instance. And right now I have to pass an integer to ResetName while keeping a counter myself inside ResetNames. But this feels not as clean and this prevents me from calling ResetName myself outside the manager class, which is valid.
How to do this better/cleaner?
As for the InternalId, it's just some id that stores the creation order for everything. So I can't just rely on these, because the numbers are large, like 32000, etc.
EDIT: Container ResetNames code:
int count = 1;
var effects = this.Effects.OrderBy ( n => n.InternalId );
foreach ( Effect effect in effects )
{
effect.ResetName ( count );
++count;
}
Have a manager class that handles the naming. It will also handle creation of the child class, and will embed a reference to itself. You can now call ResetName() on the child class, and it will have it's manager handle whatever logic needs to be done.
I'm not sure exactly what you want the results to be in various situations, but hopefully the following will be of some help:
public class Effect {
{
private EffectManager _manager;
public string Name {get;set;}
public Effect(EffectManager manager) {
_manager = manager;
}
public void ResetName() {
Name = _manager.GetNextName();
}
}
public class EffectManager {
private List<Effect> Effects;
private int currentIndex;
public Effect CreateEffect() {
var e = new Effect(this);
Effects.Add(e);
}
public string GetNextName() {
return "Effect " + currentIndex++;
}
public void ResetAllNames() {
currentIndex = 0;
foreach(var effect in Effects) {
effect.Name = GetNextName();
}
}
}
One of many possibilities: give your Effect class a public property Name, and in the method where you populate a list or array of Effect objects, assign the name. You can also give the Effect class an integer property and set the number, so that you can sort them, if you want.
public class Effect()
{
public string Name() { get; set; }
}
public class SomeClass()
{
private List<Effect> Effects;
public static void WhateverMethod()
{
for (var i = 0; i < Effects.Count; i++)
Effects[i].Name = "Effect " + (i + 1).ToString();
}
}
Are the names specific to all instance or to all instances in a given collection?
If the former you could do something like:
public class Effect
{
private static int _lastId;
public Effect()
{
InternalId = _lastId++;
}
public string Name
{
get { return "Effect" + InternalId.ToString(); }
}
public int InternalId ...
}
Namespace Diagnostics
<Conditional("DEBUG")> _
Public NotInheritable Class UniqueID
Private Shared _idBase As Integer
Private Sub New()
'keep compiler from creating default constructor
End Sub
Public Shared Function GetNext() As String
Return "ID" + System.Threading.Interlocked.Increment(_idBase).ToString("00")
End Function
End Class
End Namespace
Instead of having Name be a stored property, could you do something like this?
public class Effect
{
public int InternalId ...
public int Index;
public string BaseName;
public string Name
{
get
{
return BaseName + index;
}
}
}
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.