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.
Related
So I am learning more C# and came across this syntax:
Log.Info(() => $"Some Text {SomeVariableorProperty}");
How does this differ from the following?
Log.Info($"Some Text {SomeVariableorProperty}");
I know that the () => is basically a delegate but not sure what its purpose is here.
The scenario is:
Log.Info(() => $"Some Text {SomeSlowMethod()}");
public static string SomeSlowMethod()
{
Thread.Sleep(5000);
return "Foo";
}
Now... What happens if the logging of Info is disabled? Is the SomeSlowMethod called? The answer is no! Because the calling of the delegate () => $"Some Text {SomeSlowMethod()} is done by Log.Info() if it needs to do it. Compare it with:
Log.Info($"Some Text {SomeSlowMethod()}");
Now SomeSlowMethod() is always called, and there is the possibility that Log.Info will ignore its value.
If you think that SomeSlowMethod()s in real case scenarios don't exist, remember that even string composition is "slow" compared to other operations. Simply doing useless string.Format ($"Some Text {SomeVariableorProperty} is a string.Format) is a waste of time. And one of the laws of a good logging library is that if it isn't active it shouldn't slow your application.
To make an interesting comparison, Debug.Assert():
[Conditional("DEBUG")]
public static void Assert(bool condition, string message);
Here message is a string, but you see the [Conditional(...)]? if DEBUG isn't defined at compile time, the C# compiler can remove the whole Debug.Assert() method call, and even remove all the methods that are called inside the Debug.Assert(), so modifying possible side effects:
Debug.Assert(false, Throw());
public static string Throw()
{
throw new Exception();
}
If DEBUG isn't defined (so you are executing a RELEASE build), this will be converted to:
; // nothing
so no throw (see for example this). But note that this must be resolved at compilation time, while logging libraries are configured at runtime.
It means that the Log.Info method is expecting a function with the signature Func<String>, essentially a parameterless function that will return a string.
Passing $"Some Text {SomeVariableorProperty}" directly will fail when building, as this is a String and not a function that can be executed. That is - unless the method itself has overloads that accept just a String.
If you're in complete control over the code, then completely agree that it's a little odd, I can't see a strong reason for wanting to use a function over a String.
The only good use case for this as #KirkLarkin suggests is if the generation of that Log message needs to be done in a lazy manner. You'd probably only need this in an edge case scenario where the creating the actual message to log is an expensive operation. That way if you're call to Log.Info() decides it doesn't need to log it (e.g. it's too verbose based on a setting) you can bypass the expensive message generation. As I say though - it'd be rare that you'd come across a situation like this and probably indicates that too much is being logged.
I've been trying to approach this issue for a while now and I have not been able to find an answer.
Basically, I have a certain method that, when called, actually executes another different method rather than the method itself which I assume needs me to modify to where the method's pointer is pointing.
Say this,
public class A : OtherRandomClass
{
protected void SomeMethod()
{
//code
}
}
public class B
{
public void OtherMethod()
{
//code that I want to execute when SomeMethod is called
}
}
I cannot modify class A's source unfortunately, but what I want to try to do is to make any calls to SomeMethod actually invoke OtherMethod while preventing SomeMethod itself from being invoked, I don't want to resort to swapping method bodies.
I am aware of just how much bad practice this is, but the framework I'm using is just plain stupid and I have no other choice.
Any approaches to this?
Edit: Found what I was looking for, thanks to anyone who attempted to help!
This doesn't look simple, and to be perfectly honest, I never attempted to do such a thing.
I'd really like to know your context, because if what you want to do was my last option, I would not work with this assembly.
This answer suggests replacing the loaded method body (which is written then in Intermediate Language) with your own, by using reflection:
You can use MethodInfo.GetMethodBody().GetILAsByteArray(), modify
that, and then plug it back into MethodBuilder.CreateMethodBody().
You can then check this question and its answers to have a rough idea of how you should implement it all, but it looks like CreateMethodBody isn't fully supported and could have some unexpected behavior.
Overall, it's pretty complicated and doesn't look worth the hassle.
readonlyAction and Method must both be defined once, but assume I will assign to variableAction many times:
Action variableAction;
readonly Action readonlyAction;
void Method() {}
Which is better suited to the task, the readonly delegate, or the method? I'm thinking that there may be some optimizations happening in one case or the other, but maybe there are semantic issues to consider as well?
variableAction = readonlyAction;
variableAction = Method;
If you are the one setting up either the method or the action (pre-compilation) (which you probably would not be asking this if you werent), then I would assume that there is not a whole lot of difference performance-wise. But, you should take a look at the IL if you want the exact answer. The compiler might just create a method or inline for a static action anyway. That being said, I would focus on readability more than anything else at that point. Try to imagine a new dev trying to read the code, and if one way makes it harder to read, then use the other way....I would probably lean towards a method personally. Actions should probably be left for the scenario below:
Otherwise, the Action could be something that is passed in on construction, so you would HAVE to use the Action since you would not know the implementation until runtime anyway. But, I doubt that is why you are asking, as using the Method would be impossible in this scenario, anyway.
I have a piece of software written with fluent syntax. The method chain has a definitive "ending", before which nothing useful is actually done in the code (think NBuilder, or Linq-to-SQL's query generation not actually hitting the database until we iterate over our objects with, say, ToList()).
The problem I am having is there is confusion among other developers about proper usage of the code. They are neglecting to call the "ending" method (thus never actually "doing anything")!
I am interested in enforcing the usage of the return value of some of my methods so that we can never "end the chain" without calling that "Finalize()" or "Save()" method that actually does the work.
Consider the following code:
//The "factory" class the user will be dealing with
public class FluentClass
{
//The entry point for this software
public IntermediateClass<T> Init<T>()
{
return new IntermediateClass<T>();
}
}
//The class that actually does the work
public class IntermediateClass<T>
{
private List<T> _values;
//The user cannot call this constructor
internal IntermediateClass<T>()
{
_values = new List<T>();
}
//Once generated, they can call "setup" methods such as this
public IntermediateClass<T> With(T value)
{
var instance = new IntermediateClass<T>() { _values = _values };
instance._values.Add(value);
return instance;
}
//Picture "lazy loading" - you have to call this method to
//actually do anything worthwhile
public void Save()
{
var itemCount = _values.Count();
. . . //save to database, write a log, do some real work
}
}
As you can see, proper usage of this code would be something like:
new FluentClass().Init<int>().With(-1).With(300).With(42).Save();
The problem is that people are using it this way (thinking it achieves the same as the above):
new FluentClass().Init<int>().With(-1).With(300).With(42);
So pervasive is this problem that, with entirely good intentions, another developer once actually changed the name of the "Init" method to indicate that THAT method was doing the "real work" of the software.
Logic errors like these are very difficult to spot, and, of course, it compiles, because it is perfectly acceptable to call a method with a return value and just "pretend" it returns void. Visual Studio doesn't care if you do this; your software will still compile and run (although in some cases I believe it throws a warning). This is a great feature to have, of course. Imagine a simple "InsertToDatabase" method that returns the ID of the new row as an integer - it is easy to see that there are some cases where we need that ID, and some cases where we could do without it.
In the case of this piece of software, there is definitively never any reason to eschew that "Save" function at the end of the method chain. It is a very specialized utility, and the only gain comes from the final step.
I want somebody's software to fail at the compiler level if they call "With()" and not "Save()".
It seems like an impossible task by traditional means - but that's why I come to you guys. Is there an Attribute I can use to prevent a method from being "cast to void" or some such?
Note: The alternate way of achieving this goal that has already been suggested to me is writing a suite of unit tests to enforce this rule, and using something like http://www.testdriven.net to bind them to the compiler. This is an acceptable solution, but I am hoping for something more elegant.
I don't know of a way to enforce this at a compiler level. It's often requested for objects which implement IDisposable as well, but isn't really enforceable.
One potential option which can help, however, is to set up your class, in DEBUG only, to have a finalizer that logs/throws/etc. if Save() was never called. This can help you discover these runtime problems while debugging instead of relying on searching the code, etc.
However, make sure that, in release mode, this is not used, as it will incur a performance overhead since the addition of an unnecessary finalizer is very bad on GC performance.
You could require specific methods to use a callback like so:
new FluentClass().Init<int>(x =>
{
x.Save(y =>
{
y.With(-1),
y.With(300)
});
});
The with method returns some specific object, and the only way to get that object is by calling x.Save(), which itself has a callback that lets you set up your indeterminate number of with statements. So the init takes something like this:
public T Init<T>(Func<MyInitInputType, MySaveResultType> initSetup)
I can think of three a few solutions, not ideal.
AIUI what you want is a function which is called when the temporary variable goes out of scope (as in, when it becomes available for garbage collection, but will probably not be garbage collected for some time yet). (See: The difference between a destructor and a finalizer?) This hypothetical function would say "if you've constructed a query in this object but not called save, produce an error". C++/CLI calls this RAII, and in C++/CLI there is a concept of a "destructor" when the object isn't used any more, and a "finaliser" which is called when it's finally garbage collected. Very confusingly, C# has only a so-called destructor, but this is only called by the garbage collector (it would be valid for the framework to call it earlier, as if it were partially cleaning the object immediately, but AFAIK it doesn't do anything like that). So what you would like is a C++/CLI destructor. Unfortunately, AIUI this maps onto the concept of IDisposable, which exposes a dispose() method which can be called when a C++/CLI destructor would be called, or when the C# destructor is called -- but AIUI you still have to call "dispose" manually, which defeats the point?
Refactor the interface slightly to convey the concept more accurately. Call the init function something like "prepareQuery" or "AAA" or "initRememberToCallSaveOrThisWontDoAnything". (The last is an exaggeration, but it might be necessary to make the point).
This is more of a social problem than a technical problem. The interface should make it easy to do the right thing, but programmers do have to know how to use code! Get all the programmers together. Explain simply once-and-for-all this simple fact. If necessary have them all sign a piece of paper saying they understand, and if they wilfully continue to write code which doesn't do anythign they're worse than useless to the company and will be fired.
Fiddle with the way the operators are chained, eg. have each of the intermediateClass functions assemble an aggregate intermediateclass object containing all of the parameters (you mostly do it this was already (?)) but require an init-like function of the original class to take that as an argument, rather than have them chained after it, and then you can have save and the other functions return two different class types (with essentially the same contents), and have init only accept a class of the correct type.
The fact that it's still a problem suggests that either your coworkers need a helpful reminder, or they're rather sub-par, or the interface wasn't very clear (perhaps its perfectly good, but the author didn't realise it wouldn't be clear if you only used it in passing rather than getting to know it), or you yourself have misunderstood the situation. A technical solution would be good, but you should probably think about why the problem occurred and how to communicate more clearly, probably asking someone senior's input.
After great deliberation and trial and error, it turns out that throwing an exception from the Finalize() method was not going to work for me. Apparently, you simply can't do that; the exception gets eaten up, because garbage collection operates non-deterministically. I was unable to get the software to call Dispose() automatically from the destructor either. Jack V.'s comment explains this well; here was the link he posted, for redundancy/emphasis:
The difference between a destructor and a finalizer?
Changing the syntax to use a callback was a clever way to make the behavior foolproof, but the agreed-upon syntax was fixed, and I had to work with it. Our company is all about fluent method chains. I was also a fan of the "out parameter" solution to be honest, but again, the bottom line is the method signatures simply could not change.
Helpful information about my particular problem includes the fact that my software is only ever to be run as part of a suite of unit tests - so efficiency is not a problem.
What I ended up doing was use Mono.Cecil to Reflect upon the Calling Assembly (the code calling into my software). Note that System.Reflection was insufficient for my purposes, because it cannot pinpoint method references, but I still needed(?) to use it to get the "calling assembly" itself (Mono.Cecil remains underdocumented, so it's possible I just need to get more familiar with it in order to do away with System.Reflection altogether; that remains to be seen....)
I placed the Mono.Cecil code in the Init() method, and the structure now looks something like:
public IntermediateClass<T> Init<T>()
{
ValidateUsage(Assembly.GetCallingAssembly());
return new IntermediateClass<T>();
}
void ValidateUsage(Assembly assembly)
{
// 1) Use Mono.Cecil to inspect the codebase inside the assembly
var assemblyLocation = assembly.CodeBase.Replace("file:///", "");
var monoCecilAssembly = AssemblyFactory.GetAssembly(assemblyLocation);
// 2) Retrieve the list of Instructions in the calling method
var methods = monoCecilAssembly.Modules...Types...Methods...Instructions
// (It's a little more complicated than that...
// if anybody would like more specific information on how I got this,
// let me know... I just didn't want to clutter up this post)
// 3) Those instructions refer to OpCodes and Operands....
// Defining "invalid method" as a method that calls "Init" but not "Save"
var methodCallingInit = method.Body.Instructions.Any
(instruction => instruction.OpCode.Name.Equals("callvirt")
&& instruction.Operand is IMethodReference
&& instruction.Operand.ToString.Equals(INITMETHODSIGNATURE);
var methodNotCallingSave = !method.Body.Instructions.Any
(instruction => instruction.OpCode.Name.Equals("callvirt")
&& instruction.Operand is IMethodReference
&& instruction.Operand.ToString.Equals(SAVEMETHODSIGNATURE);
var methodInvalid = methodCallingInit && methodNotCallingSave;
// Note: this is partially pseudocode;
// It doesn't 100% faithfully represent either Mono.Cecil's syntax or my own
// There are actually a lot of annoying casts involved, omitted for sanity
// 4) Obviously, if the method is invalid, throw
if (methodInvalid)
{
throw new Exception(String.Format("Bad developer! BAD! {0}", method.Name));
}
}
Trust me, the actual code is even uglier looking than my pseudocode.... :-)
But Mono.Cecil just might be my new favorite toy.
I now have a method that refuses to be run its main body unless the calling code "promises" to also call a second method afterwards. It's like a strange kind of code contract. I'm actually thinking about making this generic and reusable. Would any of you have a use for such a thing? Say, if it were an attribute?
What if you made it so Init and With don't return objects of type FluentClass? Have them return, e.g., UninitializedFluentClass which wraps a FluentClass object. Then calling .Save(0 on the UnitializedFluentClass object calls it on the wrapped FluentClass object and returns it. If they don't call Save they don't get a FluentClass object.
In Debug mode beside implementing IDisposable you can setup a timer that will throw a exception after 1 second if the resultmethod has not been called.
Use an out parameter! All the outs must be used.
Edit: I am not sure of it will help, tho...
It would break the fluent syntax.
Using C#, I need to do some extra work if function A() was called right before function C(). If any other function was called in between A() and C() then I don't want to do that extra work. Any ideas that would require the least amount of code duplication?
I'm trying to avoid adding lines like flag = false; into every function B1..BN.
Here is a very basic example:
bool flag = false;
void A()
{
flag = true;
}
void B1()
{
...
}
void B2()
{
...
}
void C()
{
if (flag)
{
//do something
}
}
The above example was just using a simple case but I'm open to using something other than booleans. The important thing is that I want to be able to set and reset a flag of sorts so that C() knows how to behave accordingly.
Thank you for your help. If you require clarification I will edit my post.
Why not just factor your "Extra work" into a memoised function (i.e. one that caches its results)? Whenever you need that work you just call this function, which will short circuit if the cache is fresh. Whenever that work becomes stale, invalidate the cache. In your rather odd examples above, I presume you'll need a function call in each of the Bs, and one in C. Calls to A will invalidate the cache.
If you're looking for away around that (i.e. some clever way to catch all function calls and insert this call), I really wouldn't bother. I can conceive of some insane runtime reflection proxy class generation, but you should make your code flow clear and obvious; if each function depends on the work being already done, just call "doWork" in each one.
Sounds like your design is way too tightly coupled if calling one method changes the behavior of another such that you have to make sure to call them in the right order. That's a major red flag.
Sounds like some refactoring is in order. It's a little tricky to give advice without seeing more of the real code, but here is a point in the right direction.
Consider adding a parameter to C like so:
void C(bool DoExtraWork) {
if (DoExtraWork)...
}
Of course "DoExtraWork" should be named something meaningful in the context of the caller.
I solved a problem with a similar situation (i.e., the need to know whether A was called directly before C) by having a simply state machine in place. Essentially, I built a state object using an enum and a property to manage/query the state.
When my equivalent of A() was called, it would have the business logic piece store off the state indicating that A was called. If other methods (your B's ) were called, it would toggle the state to one of a few other states (my situation was a bit more complicated) and then when C() was called, the business logic piece was queried to determine if we were going to call some method D() that held the "only if A was just called" functionality.
I suspect there are multiple ways to solve this problem, but I liked the state machine approach I took because it allowed me to expand what was initially a binary situation to handle a more complicated multi-state situation.
I was fortunate that multi-threading was not an issue in my case because that tends to make things more entertaining, but the state machine would likely work in that scenario as well.
Just my two cents.
I don't recommend this, but what the hell: If you're willing to replace all your simple method calls:
A();
... with syntax like this:
// _lastAction is a class-level Action member
(_lastAction = new Action(A)).Invoke();
... then inside of C() you can just do a check like this:
void C()
{
if (_lastAction.Method.Name == "A")
{
}
}
This probably isn't thread-safe (and it wouldn't work in code run through an obfuscator without a bit of tinkering), so I wouldn't use something like this without heavy testing. I also wouldn't use something like this period.
Note: my ancient version of C# only has Action<T> (and not Action or Action<T, T> etc.), so if you're stuck there, too, you'd have to add a dummy parameter to each method to use this approach.