I wrote extension method to Timer class to destroy it after certain amount of time. seems like it actually only set false in timer.enable fields but don't really set the whole things to false. Is there a way to nullify an object from it own extension method?
and another thing - is it good practice to implement it in that way or I should expect sync issues and more surprises?
timer.DestroyAfter(1.Hours()) :
public static void DestroyAfter(this Timer timer, TimeSpan timeSpan)
{
var killingTimer = new Timer(timeSpan.TotalMilliseconds)
{
AutoReset = false,
};
killingTimer.Elapsed += (sender, e) =>
{
timer.Stop();
**timer = null;** //doesn't seem to work though line is executed
killingTimer.Stop();
killingTimer = null;
};
killingTimer.Start();
}
This would only be possible if the "this" parameter was also a ref parameter, which it is not.
So the answer is no (in the current C# implementation)
Regarding your other question: there's nothing wrong with the way you implemented it (stopping the timer and clearing the reference to the captured "killingTimer" variable).
There is nothing special about extensions methods. What the this modifier says it that call like timer.DestroyAfter(time) should be compiled as if you wrote DestroyAfter(timer, time).
And in normal methods, change to the parameter variable doesn't affect the original variable. In normal methods, there is a way to achieve that: use ref parameter. But you can't do that with the this parameter of an extension method.
Besides, this would be very confusing: If I write timer.DestroyAfter(time), then suddenly some time in the future, timer becomes null? I certainly would not expect that.
Related
can I self reference from within a method, without using the method name (for code maintenance reasons this may cause a future bug)
void SelfRef(string _Input){
if (_Input == "route1"){
//route1 calls route 2
SelfRef("route2"); //call self
}else if (_Input == "route2"){
//route2 ends
}
}
i would like to not write the word "SelfRef" again and make the function immune to future changes?
I would like to not write the word "SelfRef" again and make the function immune to future changes?
As others have said, you should simply use renaming tools if you are planning to rename a method.
But it is an interesting challenge to make a recursive function that does not refer to the name of the function. Here's a way to do it:
delegate Action<A> Recursive<A>(Recursive<A> r);
static Action<A> AnonymousRecursion<A>(Func<Action<A>, Action<A>> f)
{
Recursive<A> rec = r => a => { f(r(r))(a); };
return rec(rec);
}
Action<string> SelfRef = AnonymousRecursion<string>(
f =>
input =>
{
if (input == "route1")
f("route2");
// and so on
});
Notice how field SelfRef nowhere refers to SelfRef in its body, and yet the recursion is very straightforward; you simply recurse on f instead of SelfRef.
However I submit to you that this code is far, far harder to understand and maintain than simply writing a straightforward recursive method.
Yes, it's possible:
void Foo(int bar)
{
Console.WriteLine(bar);
if(bar < 10)
MethodBase.GetCurrentMethod().Invoke(this, new object[] {++bar});
else
Console.WriteLine("Finished");
}
but please never ever use code like this (it's ugly, it's slow, it's hard to understand, it will not work if the method is inlined).
Since you probably use an IDE like Visual Studio, renaming a method should never ever be an issue; and even if you rename the method manually you probably hit a compile time error.
You can create extension like this
public static void RecursivelyCall(this object thisObject, object [] param, [System.Runtime.CompilerServices.CallerMemberName] string methodName = "")
{
Type thisType = thisObject.GetType();
MethodInfo theMethod = thisType.GetMethod(methodName);
theMethod.Invoke(thisObject, param);
}
public static void RecursivelyCall(this object thisObject, object param, [System.Runtime.CompilerServices.CallerMemberName] string methodName = "")
{
Type thisType = thisObject.GetType();
MethodInfo theMethod = thisType.GetMethod(methodName);
theMethod.Invoke(thisObject, new object[] {param});
}
So you can use it for recursive call
private void Rec(string a)
{
this.RecursivelyCall(a);
}
But, to be honest, i don't think it is a good idea, because
function immune to future changes
doesn't worth losing code readability.
Now let's just make it clear that the technical term for "self-referencing" is recursion. And let's start looking at the problem.
You want to write a recursive method but don't want to "mention" the method name because of maintainability reasons. When I saw this I was like, "what editor are you using?". Maintainability reasons? You mean when you change the name of the method the code breaks?
These problems ca be easily fixed by using an IDE. I suggest you to use Visual Studio Community 2015. It is free and offers a wide range of features. If you want to rename a method, do this:
Right click the method name.
Select "Rename" in the context menu
Type whatever name you want it to be.
Press Enter
And you will see that magically, all the references to the method has changed their names!
So you don't need to turn the whole recursive method into a loop or something. You just need to use the right editor!
Self referencing (probably via reflection) and recursing seems quite long winded when a loop would be sufficient here:
void SelfRef(string _Input){
while(true)
{
if (_Input == "route1"){
_Input = "route2"
continue;
}else if (_Input == "route2"){
//route2 ends
break;
}
//break?
}
}
There's no construct in C# to refer to the method that you're in and call it with different parameters. You could examine the call stack to find the method name and use reflection to invoke it, but it seems pointless.
The only type of bug that you would be "immune" to is renaming the method. In that case, the build will fail and you will quickly have an indication that something is wrong.
It is possible using reflection using MethodBase.GetCurrentMethod() and it's the fastest way that I know of. Certainly faster than using Stacktraces.
You can change your code as follows:
void SelfRef(string _Input){
if (_Input == "route1"){
//route1 calls route 2
MethodBase.GetCurrentMethod().Invoke(this,new []{"route2"}); //call self
}else if (_Input == "route2"){
//route2 ends
}
}
Don't forget using System.Reflection namespace.
You are using recursion, not self reference
A function (method) calling itself is called as a recursive function and this concept is called as recursion. What you essentially have, is a recursive function called as SelfRef that takes a string as a parameter. It calls itself if the parameter is equal to "route1" which is a string.
Method reference is passing a method to another method
Method references (as called in other languages) is called as delegates in C# and that is used to pass a function itself to another function. This is mostly used to implement callbacks, i.e., event handlers. For example, you might see this code in events.
public class DelegateExample
{
public delegate void MyDelegate();
public void PrintMessage(MyDelegate d)
{
d();
}
public void PrintHello()
{
Console.WriteLine("Hello.");
}
public void PrintWorld()
{
Console.WriteLine("World.");
}
public static void Main(string[] args)
{
PrintDelegate(new MyDelegate(PrintHello));
PrintDelegate(new MyDelegate(PrintWorld));
}
}
There you see, you are passing a function as a delegate.
Use enums if you know what routes are available already
Never use strings for communicating between objects or withing the program, only use them for interacting with the user. The best bet (if the routes are pre-known) at the time of writing the program, then use enumerations for this purpose.
Calling a function by name does not cause a code-maintenance problem.
All modern development environments (e.g. Visual Studio) will automatically update every usage of that function's name, when someone renames it.
If you want to make the function immune from future changes, keep the source code to yourself.
This is purely a language matter, because I know, that this may (and possibly even should) be solved in a different way.
We have a property Prop, which in its getter has some side effects. How to "call" this property in a "nice" way to trigger these side effects?
One way:
object dummy = this.Prop;
But this doesn't seem to be a nice solution, because it involves creating unnecessary variable. I tried with:
(() => this.Prop)();
But it doesn't compile. Is there short and clean way to do it?
If you create a variable, you'll then get code complaining that it's unused, which can be annoying.
For benchmarking cases, I've sometimes added a generic Consume() extension method, which just does nothing:
public static void Consume<T>(this T ignored)
{
}
You can then write:
this.Prop.Consume();
and the compiler will be happy. Another alternative would be to put have a method which accepted a Func<T>:
public static void Consume<T>(Func<T> function)
{
function();
}
Then call it as:
Consume(() => this.Prop);
I rarely face this situation outside tests (both benchmarks, and "I should be able to call the property without an exception being thrown" test) but every so often it can be useful, e.g. to force a class to be initialized. Any time you find yourself wanting this, it's worth considering whether this would be more appropriate as a method.
Suppose I have a method like this:
public void MyCoolMethod(ref bool scannerEnabled)
{
try
{
CallDangerousMethod();
}
catch (FormatException exp)
{
try
{
//Disable scanner before validation.
scannerEnabled = false;
if (exp.Message == "FormatException")
{
MessageBox.Show(exp.Message);
}
}
finally
{
//Enable scanner after validation.
scannerEnabled = true;
}
}
And it is used like this:
MyCoolMethod(ref MyScannerEnabledVar);
The scanner can fire at any time on a separate thread. The idea is to not let it if we are handling an exception.
The question I have is, does the call to MyCoolMethod update MyScannerEnabledVar when scannerEnabled is set or does it update it when the method exits?
Note: I did not write this code, I am just trying to refactor it safely.
You can think of a ref as making an alias to a variable. It's not that the variable you pass is "passed by reference", it's that the parameter and the argument are the same variable, just with two different names. So updating one immediately updates the other, because there aren't actually two things here in the first place.
As SLaks notes, there are situations in VB that use copy-in-copy-out semantics. There are also, if I recall correctly, rare and obscure situations in which expression trees may be compiled into code that does copy-in-copy-out, but I do not recall the details.
If this code is intended to update the variable for reading on another thread, the fact that the variable is "immediately" updated is misleading. Remember, on multiple threads, reads and writes can be observed to move forwards and backwards in time with respect to each other if the reads and writes are not volatile. If the intention is to use the variable as a cross-thread communications mechanism them use an object actually designed for that purpose which is safe for that purpose. Use some sort of wait handle or mutex or whatever.
It gets updated live, as it is assigned inside the method.
When you pass a parameter by reference, the runtime passes (an equivalent to) a pointer to the field or variable that you referenced. When the method assigns to the parameter, it assigns directly to whatever the reference is pointing to.
Note, by the way, that this is not always true in VB.
Yes, it will be set when the variable is set within the method. Perhaps it would be best to return true or false whether the scanner is enabled rather than pass it in as a ref arg
The situation calls for more than a simple refactor. The code you posted will be subject to race conditions. The easy solution is to lock the unsafe method, thereby forcing threads to hop in line. The way it is, there's bound to be some bug(s) in the application due to this code, but its impossible to say what exactly they are without knowing a lot more about your requirements and implementation. I recommend you proceed with caution, a mutex/lock is an easy fix, but may have a great impact on performance. If this is a concern for you, then you all should review a better thread safe solution.
One common pattern I see and use frequently in C++ is to temporarily set a variable to a new value, and then reset it when I exit that scope. In C++, this is easily accomplished with references and templated scope classes, and allows for increased safety and prevention of errors where the variable is set to a new value, then reset to an incorrect assumed initial value.
Here is a simplified example of what I mean (in C++):
void DoSomething()
{
// The following line captures GBL.counter by reference, stores its current
// value, and sets it to 1
ScopedReset<int> resetter(GBL.counter, 1);
// In this function and all below, GBL.counter will be 1
CallSomethingThatNeedsCounterOf1();
// When I hit the close brace, ~ScopedReset will be called, and it will
// reset GBL.counter to it's previous value
}
Is there any way to do this in C#? I've found the hard way that I can't capture a ref parameter inside an IEnumerator or a lambda, which were my first two thoughts. I don't want to use the unsafe keyword if possible.
The first challenge to doing this in C# is dealing with non-deterministic destruction. Since C# doesn't have destructors you need a mechanism to control scope in order to execute the reset. IDisposable helps there and the using statement will mimic C++ deterministic destruction semantics.
The second is getting at the value you want to reset without using pointers. Lambdas and delegates can do that.
class Program
{
class ScopedReset<T> : IDisposable
{
T originalValue = default(T);
Action<T> _setter;
public ScopedReset(Func<T> getter, Action<T> setter, T v)
{
originalValue = getter();
setter(v);
_setter = setter;
}
public void Dispose()
{
_setter(originalValue);
}
}
static int counter = 0;
static void Main(string[] args)
{
counter++;
counter++;
Console.WriteLine(counter);
using (new ScopedReset<int>(() => counter, i => counter = i, 1))
Console.WriteLine(counter);
Console.WriteLine(counter);
}
}
Can you not simply copy the reference value to a new local variable, and use this new variable throughout your method, i.e. copy value by value?
Indeed, changing it from a ref to regular value parameter will accomplish this!
I don't think you can capture a ref paramenter to a local variable, and have it stay a ref - a local copy will be created.
GBL.counter is effectively an implicit, hidden parameter to CallSomethingThatNeedsCounterOf1. If you could convert it to a regular, declared paraemter your problem would go away. Also, if that would result in to many parameters, a solution would be a pair of methods which set up and reset the environment so that CallSomethingThatNeedsCounterOf1() can run.
You can create a class that calls the SetUp method in its constructor and the Reset method in Dispose(). You can use this class with the using statement, to aproximate the c++ behaviour. You would, however, have to create one of these classes for each scenario.
Short Version
For those who don't have the time to read my reasoning for this question below:
Is there any way to enforce a policy of "new objects only" or "existing objects only" for a method's parameters?
Long Version
There are plenty of methods which take objects as parameters, and it doesn't matter whether the method has the object "all to itself" or not. For instance:
var people = new List<Person>();
Person bob = new Person("Bob");
people.Add(bob);
people.Add(new Person("Larry"));
Here the List<Person>.Add method has taken an "existing" Person (Bob) as well as a "new" Person (Larry), and the list contains both items. Bob can be accessed as either bob or people[0]. Larry can be accessed as people[1] and, if desired, cached and accessed as larry (or whatever) thereafter.
OK, fine. But sometimes a method really shouldn't be passed a new object. Take, for example, Array.Sort<T>. The following doesn't make a whole lot of sense:
Array.Sort<int>(new int[] {5, 6, 3, 7, 2, 1});
All the above code does is take a new array, sort it, and then forget it (as its reference count reaches zero after Array.Sort<int> exits and the sorted array will therefore be garbage collected, if I'm not mistaken). So Array.Sort<T> expects an "existing" array as its argument.
There are conceivably other methods which may expect "new" objects (though I would generally think that to have such an expectation would be a design mistake). An imperfect example would be this:
DataTable firstTable = myDataSet.Tables["FirstTable"];
DataTable secondTable = myDataSet.Tables["SecondTable"];
firstTable.Rows.Add(secondTable.Rows[0]);
As I said, this isn't a great example, since DataRowCollection.Add doesn't actually expect a new DataRow, exactly; but it does expect a DataRow that doesn't already belong to a DataTable. So the last line in the code above won't work; it needs to be:
firstTable.ImportRow(secondTable.Rows[0]);
Anyway, this is a lot of setup for my question, which is: is there any way to enforce a policy of "new objects only" or "existing objects only" for a method's parameters, either in its definition (perhaps by some custom attributes I'm not aware of) or within the method itself (perhaps by reflection, though I'd probably shy away from this even if it were available)?
If not, any interesting ideas as to how to possibly accomplish this would be more than welcome. For instance I suppose if there were some way to get the GC's reference count for a given object, you could tell right away at the start of a method whether you've received a new object or not (assuming you're dealing with reference types, of course--which is the only scenario to which this question is relevant anyway).
EDIT:
The longer version gets longer.
All right, suppose I have some method that I want to optionally accept a TextWriter to output its progress or what-have-you:
static void TryDoSomething(TextWriter output) {
// do something...
if (output != null)
output.WriteLine("Did something...");
// do something else...
if (output != null)
output.WriteLine("Did something else...");
// etc. etc.
if (output != null)
// do I call output.Close() or not?
}
static void TryDoSomething() {
TryDoSomething(null);
}
Now, let's consider two different ways I could call this method:
string path = GetFilePath();
using (StreamWriter writer = new StreamWriter(path)) {
TryDoSomething(writer);
// do more things with writer
}
OR:
TryDoSomething(new StreamWriter(path));
Hmm... it would seem that this poses a problem, doesn't it? I've constructed a StreamWriter, which implements IDisposable, but TryDoSomething isn't going to presume to know whether it has exclusive access to its output argument or not. So the object either gets disposed prematurely (in the first case), or doesn't get disposed at all (in the second case).
I'm not saying this would be a great design, necessarily. Perhaps Josh Stodola is right and this is just a bad idea from the start. Anyway, I asked the question mainly because I was just curious if such a thing were possible. Looks like the answer is: not really.
No, basically.
There's really no difference between:
var x = new ...;
Foo(x);
and
Foo(new ...);
and indeed sometimes you might convert between the two for debugging purposes.
Note that in the DataRow/DataTable example, there's an alternative approach though - that DataRow can know its parent as part of its state. That's not the same thing as being "new" or not - you could have a "detach" operation for example. Defining conditions in terms of the genuine hard-and-fast state of the object makes a lot more sense than woolly terms such as "new".
Yes, there is a way to do this.
Sort of.
If you make your parameter a ref parameter, you'll have to have an existing variable as your argument. You can't do something like this:
DoSomething(ref new Customer());
If you do, you'll get the error "A ref or out argument must be an assignable variable."
Of course, using ref has other implications. However, if you're the one writing the method, you don't need to worry about them. As long as you don't reassign the ref parameter inside the method, it won't make any difference whether you use ref or not.
I'm not saying it's good style, necessarily. You shouldn't use ref or out unless you really, really need to and have no other way to do what you're doing. But using ref will make what you want to do work.
No. And if there is some reason that you need to do this, your code has improper architecture.
Short answer - no there isn't
In the vast majority of cases I usually find that the issues that you've listed above don't really matter all that much. When they do you could overload a method so that you can accept something else as a parameter instead of the object you are worried about sharing.
// For example create a method that allows you to do this:
people.Add("Larry");
// Instead of this:
people.Add(new Person("Larry"));
// The new method might look a little like this:
public void Add(string name)
{
Person person = new Person(name);
this.add(person); // This method could be private if neccessary
}
I can think of a way to do this, but I would definitely not recommend this. Just for argument's sake.
What does it mean for an object to be a "new" object? It means there is only one reference keeping it alive. An "existing" object would have more than one reference to it.
With this in mind, look at the following code:
class Program
{
static void Main(string[] args)
{
object o = new object();
Console.WriteLine(IsExistingObject(o));
Console.WriteLine(IsExistingObject(new object()));
o.ToString(); // Just something to simulate further usage of o. If we didn't do this, in a release build, o would be collected by the GC.Collect call in IsExistingObject. (not in a Debug build)
}
public static bool IsExistingObject(object o)
{
var oRef = new WeakReference(o);
#if DEBUG
o = null; // In Debug, we need to set o to null. This is not necessary in a release build.
#endif
GC.Collect();
GC.WaitForPendingFinalizers();
return oRef.IsAlive;
}
}
This prints True on the first line, False on the second.
But again, please do not use this in your code.
Let me rewrite your question to something shorter.
Is there any way, in my method, which takes an object as an argument, to know if this object will ever be used outside of my method?
And the short answer to that is: No.
Let me venture an opinion at this point: There should not be any such mechanism either.
This would complicate method calls all over the place.
If there was a method where I could, in a method call, tell if the object I'm given would really be used or not, then it's a signal to me, as a developer of that method, to take that into account.
Basically, you'd see this type of code all over the place (hypothetical, since it isn't available/supported:)
if (ReferenceCount(obj) == 1) return; // only reference is the one we have
My opinion is this: If the code that calls your method isn't going to use the object for anything, and there are no side-effects outside of modifying the object, then that code should not exist to begin with.
It's like code that looks like this:
1 + 2;
What does this code do? Well, depending on the C/C++ compiler, it might compile into something that evaluates 1+2. But then what, where is the result stored? Do you use it for anything? No? Then why is that code part of your source code to begin with?
Of course, you could argue that the code is actually a+b;, and the purpose is to ensure that the evaluation of a+b isn't going to throw an exception denoting overflow, but such a case is so diminishingly rare that a special case for it would just mask real problems, and it would be really simple to fix by just assigning it to a temporary variable.
In any case, for any feature in any programming language and/or runtime and/or environment, where a feature isn't available, the reasons for why it isn't available are:
It wasn't designed properly
It wasn't specified properly
It wasn't implemented properly
It wasn't tested properly
It wasn't documented properly
It wasn't prioritized above competing features
All of these are required to get a feature to appear in version X of application Y, be it C# 4.0 or MS Works 7.0.
Nope, there's no way of knowing.
All that gets passed in is the object reference. Whether it is 'newed' in-situ, or is sourced from an array, the method in question has no way of knowing how the parameters being passed in have been instantiated and/or where.
One way to know if an object passed to a function (or a method) has been created right before the call to the function/method is that the object has a property that is initialized with the timestamp passed from a system function; in that way, looking at that property, it would be possible to resolve the problem.
Frankly, I would not use such method because
I don't see any reason why the code should now if the passed parameter is an object right created, or if it has been created in a different moment.
The method I suggest depends from a system function that in some systems could not be present, or that could be less reliable.
With the modern CPUs, which are a way faster than the CPUs used 10 years ago, there could be the problem to use the right value for the threshold value to decide when an object has been freshly created, or not.
The other solution would be to use an object property that is set to a a value from the object creator, and that is set to a different value from all the methods of the object.
In this case the problem would be to forget to add the code to change that property in each method.
Once again I would ask to myself "Is there a really need to do this?".
As a possible partial solution if you only wanted one of an object to be consumed by a method maybe you could look at a Singleton. In this way the method in question could not create another instance if it existed already.