determine if a method has already been called GetValue .net - c#

Is there a .net method that determines whether or not a given method has been previously called for a given object instance?
Sometimes a property getter method has side effects. For instance, a property getter if not called previously may need to create additional objects and perform other work in order to return the value of a backing field. I can't have that happen. If the getter method hasn't been called previously, I don't need the value.
For example...
object item = something;
foreach (PropertyInfo propertyInfoForItem in item.GetProperties(Reflection.BindingFlags.Public)) {
//Need something to avoid calling this if the property getter method has not been previously been called for this item
object itemPropertyValue = nothing;
itemPropertyValue = propertyInfoForItem.GetValue(item, null);
}
I've looked through the MethodInfo class returned from PropertyInfo.GetGetMethod() and didn't spot anything there that would help.
Any ideas?
As an additional note based on feedback (and thanks for chiming in!), I wouldn't be able to modify the existing objects I'm inspecting.

I think your way of achieving this goal is overly complicated. You can simply use a bool or numeric class-level variable for this purpose.
public class C
{
private int _counter = 0;
// private bool _methodCalled = false;
public void M()
{
// check the state of _counter or _methodCalled
_counter++;
// _methodCalled = true;
}
}
You can make the private variable static if you want to take all calls into account, regardless of the instance of the class that was used to invoke it.
Note that locking may be necessary if there is some multi-threading going on and you have conditional branching depending on the counter.
EDIT
Since the class cannot be modified (as stated in the comment), you'll need to create a wrapper class that will aggregate your class and hold the counter.
public class CWrapper
{
private int _counter = 0;
private C _c = new C();
public M()
{
if (_counter == 0)
{
_c.M();
}
counter++;
}
}

Since you've stated a few times that you do not have the ability to modify the objects in question, your only option is going to be to implement wrapper classes for those object types. In your wrapper class you can expose all of the properties and methods on the objects in question, but you can implement in your wrapper Getters the reference counting suggested in the other answers.
If you need to determine if a Getter has been called before you have access to the object, I'm afraid you are out of luck.

You could make a static count within the class and then within the method for the first time increment to 1 if 0 and subsequent times if 1 then you know it has been called already and you can return -1 or whatever.

You can use the decorator design pattern in order to do it.
class Program
{
static void Main(string[] args) {
var hasDoMethodInstance = new HasDoMethodImpl();
var hasDoMethodDecoratorInstance = new HasDoMethodDecorator(hasDoMethodInstance);
hasDoMethodDecoratorInstance.Do();
}
}
public interface IHasDoMethod
{
void Do();
}
public class HasDoMethodDecorator : IHasDoMethod
{
private int counter = 0;
private readonly IHasDoMethod hasDoMethod;
public HasDoMethodDecorator(IHasDoMethod hasDoMethod) {
this.hasDoMethod = hasDoMethod;
}
public void Do() {
hasDoMethod.Do();
counter++;
}
}
public class HasDoMethodImpl : IHasDoMethod
{
public void Do() {
//Your logic
}
}

Related

Can a static member variable be used to cache a value in a static class?

I've come across this piece of code where it looks like the original developer has tried to use a static string to cache a value in a static class.
public static class GetStringFromSomeProcess
{
private static string theAnswer;
public static string GetString
{
get
{
if(theAnswer == null)
{
theAnswer = GoGetTheAnswerFromALongRunningProcess();
}
return theAnswer;
}
}
}
As far as I can see this won't work, as you can't instantiate the GetStringFromSomeProcess class, GoGetTheAnswerFromALongRunningProcess will be called every time GetString is used. Am I missing something?
This will work fine - there is only one instance of theAnswer because it is static - and (also because it is static) it can be accessed from a public static property. This means that any changes made to it will be visible to all code that accesses it. So the first call to GetString will set theAnswer to non-null, and subsequent calls will not make a call to GetStringFromSomeProcess().
However, the solution you posted is not threadsafe because GoGetTheAnswerFromALongRunningProcess() could be called simultaneously by multiple threads.
.Net provides the Lazy class to solve this issue, as follows:
public static class GetStringFromSomeProcess
{
private static readonly Lazy<string> _theAnswer = new Lazy<string>(GoGetTheAnswerFromALongRunningProcess);
public static string GetString
{
get
{
return _theAnswer.Value;
}
}
public static string GoGetTheAnswerFromALongRunningProcess()
{
return "X";
}
}
You supply to the constructor of the Lazy<T> class a method that it can call when needed in order to create the object that it is wrapping. In the example above, I pass GoGetTheAnswerFromALongRunningProcess to its constructor.
Also note that it's usually a bad idea to have a property that can take a very long time to return. It's better to make it a method:
public static string GetString()
{
return _theAnswer.Value;
}
You are right in saying that the class can't be instantiated, but the class will exist within the application.
Therefore, only the first time the property is accessed, will the method GetStringFromSomeProcess be called. Every other time after that, the check for == null will resolve to false and the value evaluated by the first call will be returned.
Does it work correctly without creating an object of the GetStringFromSomeProces class? Since the string, theAnswer, is also static, it could potentially work, but I'm wondering when that variable will be initialized. Typically you would code it like you are suggesting with initialization of the GetStringFromSomeProcess Class.
Main.cs
...
GetStringFromSomeProcess getString = new GetStringFromSomeProcess();
string answer = getString.theAnswer();
...
GetStringFromSomeProcess.cs
public class GetStringFromSomeProcess
{
private string _theAnswer;
public string theAnswer
{
get
{
if(theAnswer == null)
{
GoGetTheAnswerFromALongRunningProcess getAnswer = new GoGetTheAnswerFromALongRunningProcess();
_theAnswer = getAnswer.GetAnswer();
}
return _theAnswer;
}
}
}

How to make a class with multiple methods that return a value?

I have created a class that needs to alter a variable's value when it is instantiated.
Example:
In my LrgDialogBox class I might have:
public LrgDialogBox(ref oldResult)
{
// bunch of code
UserInput();
}
public UserInput()
{
newResult=false;
}
In my main class I create an object of my LrgDialogBox called lrgDia then I type:
lrgDia = new LrgDialogBox(ref result);
if (result==true) this.exit;
I basically need to know how to make the reference variable "oldResult" private in my LrgDialogBox class, so that any method can alter its value so it can be used in my main class. Hopefully without changing the parameters of my other methods. Please help.
Kris
There isn't any way for you to meaningfully store the reference parameter that is passed in and be able to modify its value later. What you need to do is add in another layer of indirection; create a reference type that holds onto the value that you really care about. Pass around references to that type, and then all of those references are indirectly pointing to a single value.
The implementation of such a wrapper is simple:
public class Wrapper<T>
{
public T Value { get; set; }
}
You can now create a class that accepts a Wrapper<bool> in the constructor, and then modifies the value within that wrapper at a later point in time.
public class Foo
{
private Wrapper<bool> flag;
public Foo(Wrapper<bool> flag)
{
this.flag = flag;
}
public void Bar()
{
flag.Value = false;
}
}
The other option available to you, since you are, in this case, only calling the method from within the constructor, is to simply have your other method return its value, rather than setting a private field. This would be the preferred design:
public class LrgDialogBox
{
public LrgDialogBox(ref bool oldResult)
{
// bunch of code
oldResult = UserInput();
}
public bool UserInput()
{
return false;
}
}
Just use a private variable to work with during the processing.
private bool _newResult;
public LrgDialogBox(ref bool oldResult)
{
// bunch of code
_newResult = oldResult;
UserInput();
oldResult = _newResult;
}
private void UserInput()
{
_newResult = false;
}

get the value of a public int from a different class

I have a button click event in class1test where I want to set the value of d_testNumber to 3. Then in class 2test I want to be able to do an if test and if d_testNumber show a message box. My problem is that d_testNumber is always 0 in class 2test. Can someone tell me how to get the value from class 1test d_testNumber to class 2test?
This is in class 1test:
public int d_testNumber = 0;
Method in class 1test :
void miEditCopay_Click(object sender, Telerik.Windows.RadRoutedEventArgs e)
{
d_testNumber = 3;
}
This is in class 2test:
public int d_testNumber;
Method in class 2test:
public void HelloMessage();
if (d_testNumber == 3)
{
messagebox.show('test worked');
}
If it's a public instance property on the class, like this:
public Class Alpha
{
public int DTestNumber ;
}
Then the other class needs a reference to the appropriate instance of the other class in order to examine it. How that reference is obtained is up to you and the design of your program. Here's an example:
public class Bravo
{
public void SomeMethod()
{
Alpha instance = GetAnInstanceOfAlpha() ; // might be passed as a parameter
if ( instance.DTestNumber == 3 )
{
messagebox.Show('test worked') ;
}
return ;
}
If it's a public static property on the class, like this:
public Class Alpha
{
public static int DTestNumber ;
}
Then in the other class you can do something like this:
public class Bravo
{
public void SomeMethod()
{
if ( Alpha.DTestNumber == 3 )
{
messagebox.Show('test worked') ;
}
return ;
}
Note that static members are singletons with respect to the application domain and the class (Note: statics are per-class properties, not per-intance). Further, if your application is multi-threaded (like a windows program almost certainly is), any changes made to static members are a guaranteed race condition unless you take pains to serialize access via the many synchronization primitives available to you (e.g., the lock statement).
Head First Labs produces some excellent books for self-learning. If you're new to programming, cruise over to Head First Labs and get their Head First Programming: A learner's guide to programming using the Python language (and yes, it does use Python, but for most languages, the skill of programming is not related to the language used.
If you already know something about programming, but are new to C#, then get get a copy of, Head First C#: A Learner's Guide to Real-World Programming with C#, XAML, and .NET. Highly recommended.
if you want to use the same value as defined in class 1 then you have 3 options
Make the variable static in first
if you don't want to make it static you need to pass the value to the other class
Example of 1:
public static int d_testNumber = 0;
if (Class1test.d_testNumber == 3)
{
//your code
}
Use static in declaration.
public static int d_testNumber = 0;
You would have to specify further. You have a d_testnumber field in both classes, and the 2test class will use the variable of its own.
If you have an 2test object called 2testObject somewhere, you can do:
void miEditCopay_Click(object sender, Telerik.Windows.RadRoutedEventArgs e)
{
2testObject.d_testNumber = 3;
}
And pass 2testObject to the HelloMessage() method
Maybe you want d_testNumber to be static so both classes can easily access it?
in 1test:
public static int d_testNumber;
//rest of code the same
in 2test:
if (1test.d_testNumber == 3)
{
//code
}
(Assuming both classes are in the same project / namespace, if not you may need a reference / using statement at the top)

Create a single delegate for all objects instead of one delegate per object

I have an object pool, and I need to call a delegate method OnFree(), whenever I call Free() on an object in the pool.
Free() is created externally and set on the object when the pool is created. OnFree differs from one object to another, and sometimes it is even null.
Objects in the pool inherit from the Poolable class.
class Poolable
{
public Action Free();
public Action OnFree();
}
Currently I create OnFree in the inheriting class by doing this:
class Light
{
public Light()
{
// Create method to be called when Free() is called on this light.
OnFree = () =>
{
DoStuffHere();
};
}
}
However, this will create a separate delegate for each light, which wastes a bunch of memory especially when there are tens of thousands of objects in the pool. Er, it does create a new delegate every time this constructor is called, right?
What is a good way to allow objects to create their own OnFree() delegate, so that there is only one delegate per object type, instead of one delegate per instance?
I can think of a way of course, but I'm hoping someone can think of a "good" way -- something that allows easy maintainability.
Edit: Can I make the OnFree() delegate static in the base class, so that it is static per inherited type somehow?
Edit: To clarify how Pool is used, and why Free() is a delegate, not a virtual method. Please let me know if you can think of a better way to do this.
public class Pool<T> where T : Poolable
{
private int _liveCount;
private T[] _pool;
[...]
public Pool(int capacity, Func<T> allocateFunction)
{
[...]
// Fill pool with initial items:
for (int i = 0; i < capacity; i++)
{
T item = _allocate();
item.Free = () => Free(item);
_pool[i] = item;
}
}
/// <summary>
/// Frees given object from this pool. Object is assumed to
/// be in this pool.
/// </summary>
public void Free(Poolable obj)
{
obj.OnFree();
_liveCount -= 1;
[...]
}
}
How about keeping it simple:
class Poolable
{
public virtual void Free() { }
public virtual void OnFree() { } // naming not according to BCL std
}
class Light : Poolable
{
public override void Free() { }
...
}
your example shows no need for delegates (over virtual methods)
proper encapsulation would require events instead of public delegates
looks like you are optimizing prematurely.
It actually depends on where DoStuffHere() is defined. If this is an instance method, there is an implicit capture of this onto a compiler-generated type; likewise anything else (not shown in your example) might be captured.
In most normal cases the extra overhead of a delegate instance is minimal. One workaround to avoid passing creating a delegate is to have a parameterised delegate (an Action<SomeStateType>, perhaps stored in a static field), and feed the state in as a separate parameter... but of course, then you are creating an object for the state! The slight advantage of doing a manual capture is that you are probably (it depends on the exact code sample) reducing it from 2 (or more) allocations (1 delegate, 1-or-more capture classes) to 1 allocation (your manual capture; the delegate being held on a static field).
One way of another, there is likely going to be something created. Personally, until your profiling shows it is a bottleneck, I think you should relax a bit - allocations are very fast, and most times the object will be collected in GEN-0, which is very efficient.
If you use a static generic class you get one "instance" per type - which is exactly what you were after. Hence, using such a class as the backstore for your type-specific delegates, and initialize them in the static constructor of each Poolable sub-class would solve your problem. See the sample code:
public class Poolable
{
public Action Free { get; set; }
public Action OnFree { get { return GetOnFree(); } }
protected virtual Action GetOnFree() { throw new NotImplementedException(); }
}
public static class PoolHelper<T> where T : Poolable
{
public static Action OnFree { get; set; }
}
public class Light : Poolable
{
static Light()
{
PoolHelper<Light>.OnFree = () =>
{
// Define 'OnFree' for the Light type here...
// and do so for all other other sub-classes of Poolable
};
}
protected override Action GetOnFree()
{
return PoolHelper<Light>.OnFree;
}
}

how to destroy a Static Class in C#

I am using .net 1.1. I have a session class in which I have stored many static variables that hold some data to be used by many classes.
I want to find a simple way of destroying this class instead of resetting every variable one by one. For example if there is a static class MyStatic, I would have liked to destroy/remove this class from the memory by writing MyStatic = null, which is not currently possible,
Additional question.
The idea of singleton is good, but I have the following questions:
If singleton is implemented, the 'single' object will still remain in the memory. In singleton, we are only checking if an instance is already existing. how can i make sure that this instance variable also gets destroyed.
I have a main class which initializes the variable in the static class. Even if I plan to implement a Rest() method, I need to call it from a method, for eg, the destructor in the main class. But this destructor gets called only when GC collects this main class object in the memory, which means the Reset() gets called very late
thanks
pradeep
Don't use a static class to store your variables. Use an instance (and make it a singleton if you only want one instance at any given time.) You can then implement IDisposible, and just call Dispose() when you want to destroy it.
For more information check out this site: http://csharpindepth.com/Articles/General/Singleton.aspx
EDIT
The object is still subject to garbage collection, so unless you are using lots of unmanaged resources, you should be fine. You can implement IDisposible to clean up any resources that need to be cleaned up as well.
Instead of a static class, have a static instance of a class:
class Foo
{
public int Something;
public static Foo Instance = new Foo();
public void Reset()
{
Instance = new Foo();
}
}
void test
{
int i = Foo.Instance.Something;
}
You can also delegate to an instance of the class:
class Foo
{
public int Something
{
get { return instance.something; }
}
private int something;
private static Foo instance = new Foo();
public void Reset()
{
instance = new Foo();
}
}
void test
{
int i = Foo.Something;
}
There's no way to destroy a static unless it resides in a separate AppDomain in which case you can get rid of it by unloading the AppDomain. However it is usually better to avoid statics.
EDIT: Additional question
When the singleton is no longer referenced it will be collected just as everything else. In other words, if you want it collected you must make sure that there are no references to it. It goes without saying that if you store a static reference to your singleton, you will have the same problem as before.
Use a Singleton like ktrauberman said, and have an initialization method or a reset method. You only have to write the code once and call the method.
You destroy objects, not classes. There's nothing wrong with static classes--C# provides them for a reason. Singletons are just extra overhead, unless you actually need an object, e.g. when you have to pass the object as a parameter.
Static classes contain only static variables. These variables tend to last for the lifetime of the app, in which case you don't have to worry about disposing referenced objects, unless you have a mild case of OCD. That just leaves the case where your static class allocates and releases resources throughout its lifetime. Dispose of these objects in due course as you usually would (e.g., "using...").
The best way in your condition is to have an Reset() method built-in as well, which can reset the values of the class.
class myclass
{
private static myclass singleobj = null;
private myclass(){}
public static myclass CreateInstance()
{
if(singleobj == null)
singleobj = new myclass();
return singleobj
}
}
Building on Ahemd Said's answer: (and props to him!)
class Singleton
{
private static Singleton instance = null;
private Singleton(){} // private constructor: stops others from using
public static Singleton Instance
{
get { return instance ?? (instance = new Singleton()); }
set {
if (null != value)
{ throw new InvalidValueException(); }
else
{ instance = null; }
}
}
}
void SampleUsage()
{
Singleton myObj = Singleton.Instance;
// use myObj for your work...
myObj.Instance = null; // The set-operator makes it ready for GC
}
(untested... but mostly right, I think)
You could also add in usage of the IDispose interface for more cleanup.
You can create a method in the static class which resets the values of all properties.
Consider you have a static class
public static class ClassA
{
public static int id=0;
public static string name="";
public static void ResetValues()
{
// Here you want to reset to the old initialized value
id=0;
name="";
}
}
Now you can use any of the below approaches from any other class to reset value of a static class
Approach 1 - Calling directly
ClassA.ResetValues();
Approach 2 - Invoking method dynamically from a known namespace and known class
Type t1 = Type.GetType("Namespace1.ClassA");
MethodInfo methodInfo1 = t1.GetMethod("ResetValues");
if (methodInfo1 != null)
{
object result = null;
result = methodInfo1.Invoke(null, null);
}
Approach 3 - Invoking method dynamically from an assembly/set of assemblies
foreach (var Ass in AppDomain.CurrentDomain.GetAssemblies())
{
// Use the above "If" condition if you want to filter from only one Dll
if (Ass.ManifestModule.FullyQualifiedName.EndsWith("YourDll.dll"))
{
List<Type> lstClasses = Ass.GetTypes().Where(t => t.IsClass && t.IsSealed && t.IsAbstract).ToList();
foreach (Type type in lstClasses)
{
MethodInfo methodInfo = type.GetMethod("ResetValues");
if (methodInfo != null)
{
object result = null;
result = methodInfo.Invoke(null, null);
}
}
break;
}
}
Inject the objects into the static class at startup from a non static class that implements IDisposable, then when your non static class is destroyed so are the objects the static class uses.
Make sure to implement something like "Disable()" so the static class is made aware it's objects have just been set to null.
Eg I have a logger class as follows:
public static class Logger
{
private static Action<string, Exception, bool> _logError;
public static void InitLogger(Action<string, Exception, bool> logError)
{
if(logError != null) _logError = logError;
}
public static void LogError(string msg, Exception e = null, bool sendEmailReport = false)
{
_logError?.Invoke(msg, e, sendEmailReport);
}
In my constructor of my Form I call the following to setup the logger.
Logger.InitLogger(LogError);
Then from any class in my project I can do the following:
Logger.LogError("error",new Exception("error), true);

Categories