Swapping method pointers - c#

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.

Related

How to force 2 C# methods always appear together in compile time?

I have two C# methods RegisterTasks() and WaitForAll(), and whenever RegisterTasks() is called, WaitForAll() must be called in the same code block too. Just wondering if there's a way to tell C# compiler to make sure WaitForAll() always appear together with RegisterTasks(), and give a compiling error otherwise?
Thanks~
Reduce the visibility of RegisterTasks() and WaitForAll(), and expose a method that calls them both.
The short answer, as everyone else has said, is no.
I assume these methods are separate because the caller may wish to execute other code in between them. You may wish to consider creating a single combined method that takes a delegate as a parameter and then invokes that delegate when desired.
No. You need to properly document the contract and trust the end user to use the methods correctly.
No but you can do some designs. Example:
public void RegisterTasks(){
// do something
WaitForAll();
}
Or
public void RegisterTasks(){
// do something
privateWaitForAll();
}
public void WaitForAll(){
// do something
privateWaitForAll();
}
private void privateWaitForAll(){
// do something
}

C# Boilerplate code

I'm thinking of building some generic extensions that will take a way all these null, throw checks and asserts and instead use fluent APIs to handle this.
So I'm thinking of doing something like this.
Shall() - Not quite sure about this one yet
.Test(...) - Determines whether the contained logic executed without any errors
.Guard(...) - Guards the contained logic from throwing any exception
.Assert(...) - Asserts before the execution of the code
.Throw(...) - Throws an exception based on a certain condition
.Assume(...) - Similar to assert but calls to Contract.Assume
Usage: father.Shall().Guard(f => f.Shop())
The thing is that I don't want these extra calls at run-time and I know AOP can solve this for me, I want to inline these calls directly to the caller, if you have a better way of doing that please do tell.
Now, before I'm researching or doing anything I wonder whether someone already done that or know of a tool that is doing it ?
I really want to build something like that and release it to public because I think that it can save a lot of time and headache.
Some examples.
DbSet<TEntity> set = Set<TEntity>();
if (set != null)
{
if (Contains(entity))
{
set.Remove(entity);
}
else
{
set.Attach(entity);
set.Remove(entity);
}
}
Changes to the following.
Set<TEntity>().Shall().Guard(set =>
{
if (Contains(entity))
{
set.Remove(entity);
}
else
{
set.Attach(entity);
set.Remove(entity);
}
});
Instead of being funny and try to make fun of other people, some people can really learn something about maturity, you can share your experience and tell me what's so good or bad about it, that I'll accept.
I'm not trying to recreate Code Contracts, I know what it is I'm using it everyday, I'm trying to move the boilerplate code that is written to one place.
Sometimes you have methods that for each call you have to check the returned object and is not your code so you can't ensure that the callee won't result a null so in the caller you have to perform null checks on the returned object so I thought of something that may allow me to perform these checks easily when chaining calls.
Update: I'll have to think about it some more and change the API to make the intentions clear and the code more readable.
I think that the idea is not polished at all and that indeed I went too far with all these methods.
Anyways, I'll leave it for now.
It sounds like you're describing something like Code Contracts: http://msdn.microsoft.com/en-us/devlabs/dd491992
If I understand what you're looking for, then the closest thing I've come up with is the extension method:
public static Chain<T>(this T obj, Action<T> act)
{
act(obj);
return obj;
}
This allows you to do the following:
Set.Remove(Set.FirstOrDefault(entity) ?? entity.Chain(a => Set.Add(a)));
As you can see, though, this isn't the most readable code. This isn't to say that Chain extension method is bad (and it certainly has its uses), but that Chain extension method can definitely be abused, so use cautiously or the ghost of programming past will come back to haunt you.

How to enforce the use of a method's return value in C#?

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.

How do I automatically reset a boolean when any method other is called in C#?

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.

C#: Why can't we have inner methods / local functions?

Very often it happens that I have private methods which become very big and contain repeating tasks but these tasks are so specific that it doesn't make sense to make them available to any other code part.
So it would be really great to be able to create 'inner methods' in this case.
Is there any technical (or even philosophical?) limitation that prevents C# from giving us this? Or did I miss something?
Update from 2016: This is coming and it's called a 'local function'. See marked answer.
Well, we can have "anonymous methods" defined inside a function (I don't suggest using them to organize a large method):
void test() {
Action t = () => Console.WriteLine("hello world"); // C# 3.0+
// Action t = delegate { Console.WriteLine("hello world"); }; // C# 2.0+
t();
}
If something is long and complicated than usually its good practise to refactor it to a separate class (either normal or static - depending on context) - there you can have private methods which will be specific for this functionality only.
I know a lot of people dont like regions but this is a case where they could prove useful by grouping your specific methods into a region.
Could you give a more concrete example? After reading your post I have the following impression, which is of course only a guess, due to limited informations:
Private methods are not available outside your class, so they are hidden from any other code anyway.
If you want to hide private methods from other code in the same class, your class might be to big and might violate the single responsibility rule.
Have a look at anonymous delegates an lambda expressions. It's not exactly what you asked for, but they might solve most of your problems.
Achim
If your method becomes too big, consider putting it in a separate class, or to create private helper methods. Generally I create a new method whenever I would normally have written a comment.
The better solution is to refactor this method to separate class. Create instance of this class as private field in your initial class. Make the big method public and refactor big method into several private methods, so it will be much clear what it does.
Seems like we're going to get exactly what I wanted with Local Functions in C# 7 / Visual Studio 15:
https://github.com/dotnet/roslyn/issues/2930
private int SomeMethodExposedToObjectMembers(int input)
{
int InnerMethod(bool b)
{
// TODO: Change return based on parameter b
return 0;
}
var calculation = 0;
// TODO: Some calculations based on input, store result in calculation
if (calculation > 0) return InnerMethod(true);
return InnerMethod(false);
}
Too bad I had to wait more than 7 years for this :-)
See also other answers for earlier versions of C#.

Categories