Is there a way I could use reflection to hook one function to another without using delegates?
class A
{
void Foo()
{
}
}
class B
{
void Main()
{
A a = new A();
a.GetType().GetMethod("Foo").AddHook(a, Func); //I want something like this
a.Foo();
//Func gets called
}
void Func()
{
}
}
Is there a way to call Func after Foo was called without using events, delegates or just calling Func from inside Foo?
I need this so my game's UI controller can get updated.
The way I see most people dealing with this is by adding a bunch of events to A and subscribing B to those. Like this
class A
{
public delegate void UICallback();
public event UICallback onFoo;
void Foo()
{
onFoo.Invoke();
}
}
class B
{
void Main()
{
A a = new A();
a.onFoo += Func;
a.Foo();
}
void Func()
{
}
}
The problem I find with this approach is that I'd need to add a bunch of events like these (probably more than 5 or even 10) to many classes and then remember to invoke those at the end of a function to update UI (invoke onBattleStarted at the end of StartBattle(), for example). This, in addition to increasing the size of my classes with big blocks of event declarations making it ugly to read, makes it a harder maintain.
EDIT I think no one really understands what I'm looking for... I'd like a way to hook Func to Foo without making any changes to Foo, i.e. without Foo knowing this callback exists. Using an action won't help since I'd need specify on Foo's parameters that it should call Func
Thank you for your help!
You Can call Action at the end of Func().
Class A
{
void Foo()
{
}
}
Class B
{
void Main()
{
A a = new A();
Func( () => {a.Foo();});
}
void Func(Action onFinish)
{
//Enter your code here
onFinish();
}
There is the method chaining pattern if that can solve your problem:
namespace Assets
{
public class Example
{
public Example GrabSomeFoodInTheFridge()
{
// some work
return this;
}
public Example WatchTv()
{
// some work
return this;
}
public Example EatFood()
{
// some work
return this;
}
}
public class Demo
{
public Demo()
{
var example = new Example();
var instance = example
.GrabSomeFoodInTheFridge()
.EatFood()
.WatchTv();
}
}
}
It does not use reflection at all, additionally you could leverage interfaces and extension methods.
This question already has answers here:
Cannot use 'this' in member initializer?
(3 answers)
Closed 7 years ago.
Why does the compiler give an error about this being unavailable that when initializing an instance variable when defining it?
Keyword 'this' is not available in the current context
The constructor initialization is fine. I understand the scenario here - I just wanted to find the reason (via MSDN or otherwise) why "this" is available to a constructor but not directly if initializing the member variable.
Here is a simple abstraction of the error I'm seeing.
public class ClassA
{
// Gets compiler error that "this" unavailable
protected ClassB _a1 = new ClassB(this);
// Works fine
protected ClassB _a2;
public ClassA() { _a2 = new ClassB(this); }
}
public class ClassB
{
public ClassA A { get; private set; }
public ClassB(ClassA a) { this.A = a; }
}
I was hoping to keep my initialization next to the assignment since the above example is an abstraction of my code where I am defining Lazy valueFactory delegates for 10-15 member variables in which the delegates need the data context passed as a parameter to the constructor. With 15 member variables, I'd prefer to keep the assignment next to the definition on a single line instead of having 15 lines of definitions and then another 15 lines in the constructor initializing each one.
This is basically what I had to do in my actual code:
public class MyContext
{
public ProgramService Programs { get { return _programs.Value; } }
protected Lazy<ProgramService> _programs;
public MyContext()
{
_programs = new Lazy<ProgramService>(() => new ProgramService(this));
}
}
Basically to keep you from relying on the order (textual) and possibly non-usable state of the class under construction. I think the overriding principle at stake is that if it's "complicated" logic, then you should be using a constructor.
Eg., doing this:
class A {
private int x = 1;
private int y = this.x + 1;
}
would lead to different results than:
class A {
private int y = this.x + 1;
private int x = 1;
}
which is a little unexpected. To side-step the issue, but still allow the convenience of inline init - disallowing this makes the ordering not matter.
In your actual code, you could possibly do a lazy check to keep things located together:
public ProgramService Programs {
get {
if (_programs == null) _programs = new ProgramService(this);
return _programs.Value;
}
}
// change this to private to keep subclasses from accessing a possibly null reference
private Lazy<ProgramService> _programs;
I have trouble understanding lambdas, delegates and so on, I hope with someone giving me a solution to my problem I am able to understand those better. Basically it is possible to create (or change) the body of a method when an object of the class is initialized, no?
Kinda like this:
Let's say I have 1 classes: Class A, which looks like this:
public class ClassA{
int i;
public ClassA(int number)
{
i = number;
}
public void Foo(){}
}
For demonstration purposes very minimalistic, now I also have somewhere else the static main, and what I want to do there is following: Creating multiple objects of ClassA and make it so that when I call ClassA.Foo I get different results I can determine myself, how is it supposed to look Syntax wise?
static void Main(string[] args)
{
ClassA FooBlue = New ClassA(1){
public void Foo()
{
System.Console.WriteLine("I am a Fooranger Blue!");
};
ClassA FooPink = New ClassA(2){
public void Foo()
{
System.Console.WriteLine("My color is the manliest!");
};
...
So now when I do this:
...
FooBlue.Foo();
FooPink.Foo();
System.Console.ReadLine();
}
I get following output on the console:
"I am a Fooranger Blue!"
"My color is the manliest!"
I just mention again that this is an example and by no means anything out of praxis but for the purpose of me understanding that stuff it would be great if someone can provide an answer that gives the desired solution, including the useless integer i.
To accomplish the goal of "providing the implementation of a method when constructing the type" you can indeed use delegates. Simply accept a delegate when constructing the object and invoke it when you want it to be executed:
public class ClassA
{
private Action action;
public ClassA(Action action)
{
this.action = action;
}
public void Foo()
{
action();
}
}
The syntax for a lambda is different than the syntax for creating a named method from a class' definition:
var fooBlue = new ClassA(() => Console.WriteLine("I am a Fooranger Blue!"));
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I sometimes need to go online and find a tutorial for something. I am often finding that some people put code like this:
this.button1.Text = "Random Text";
Then I find code that is just like this:
button1.Text = "Random Text";
Is it better to use the this.whatever or does it not matter?
It depends. Here's an example class:
class A
{
private int count;
public A(int count)
{
this.count = count;
}
}
In this case, the "this." is mandatory because it disambiguates the reference on the left of the assignment. Without it, it is not clear to you reading the code whether "count" would refer to the parameter or the field. (It is clear to the compiler, which has rules to follow.) But in most cases, it is purely a matter of preference.
Write all your code to emphasize salient points to the reader. If you feel that it is important for the reader to clearly understand that an identifier refers to an instance member then use this. If you feel that its an unimportant and distracting implementation detail, don't. Use good judgment to make your code readable.
this is just to make it clear, in some cases we have to use this:
Differentiate between parameter and local member:
//local member
object item;
private void SomeMethod(object item){
this.item = item;//must use this
}
Pass the current class instance into another method:
public class SomeClass {
private void SomeMethod(SomeClass obj){
//....
}
private void AnotherMethod(){
SomeMethod(this);//pass the current instance into SomeMethod
//.....
}
}
Use in extension methods:
public static class SomeClassExtension {
public static void SomeClassMethod(this SomeClass obj){
//use obj as a reference to the object calling this method...
}
}
Call a constructor from another constructor (with different signature):
public Form1(string s) : this() {//Call the Form1() before executing other code in Form1(string s)
//......
}
Use for declaring indexers:
public class SomeClass {
//declare an index returning a string
public string this[int index] {
get {return ...}
set { ... }
}
}
Use auto-properties in struct:
public struct SomeStruct {
public object AutoProp1 {get;set;}
public object AutoProp2 {get;set;}
public SomeStruct() : this() //must use this
{
AutoProp1 = someObject;
AutoProp2 = someObject;
}
}
Cast the current instance to the based classes/types:
public class ClassB : ClassC {
//...
}
public class ClassA : ClassB {
public ClassA(){
((ClassC)this).MemberOfClassC ... ;//There might be some member in ClassC
//which is overridden in ClassA or ClassB, casting to ClassC can help we invoke the original member instead of the overridden one.
}
}
There might be some other uses of this, however I'll update later if I think out.
It does not matter, it is a matter of style. I tend to omit this, since it is just extra code to mentally parse.
The only case it matters is when there is a naming conflict between local and instance variables, in which case this can be used to disambiguate between a field and a local variable.
Here is an example of the type of situation where it does matter:
public class Foo
{
private string x;
public Foo(string x)
{
// x = x; Assigns local parameter x to x, not what we want
this.x = x; // Assigns instance variable x to local parameter x: this disambiguates between the two.
}
}
an example of using this can be to access class variable when you already have a similar variable in the scope. Otherwise it is mostly of choice.
Example
public class Test
{
public string firstName { get; set; }
public void temp(string firstName)
{
firstName = this.firstName;
}
}
In regards to fields the only case where this is explicitly needed is when there is a naming conflict:
public class Foo
{
private string bar;
public Foo(string bar)
{
this.bar = bar;
}
}
So some will prepend an underscore:
public class Foo
{
private string _bar;
public Foo(string bar)
{
_bar = bar;
}
}
Usually it will not matter. This reason why you might use this. is to explicit say that you want to reference a property/field that belong to the current class.
Again, there are not many occasions when you are likely to need this, but for example you might have a local variable with the same name as a class level property/field. Then you could use this..
For example:
class MyClass
{
string s = "1";
void MyFunction(string s)
{
//s = local value as passed in to function
//this.s = "1"
}
}
It doesn't usually matter. The this keyword "refers to the current instance of the class and is also used as a modifier of the first parameter of an extension method."
Check out this article.
http://msdn.microsoft.com/en-us/library/dk1507sz.aspx
generally it doesn't matter, but if you pass in a variable called, say button1, to a class method that already has a member called button1, then you'll need to disambiguate which one you really meant.
This is probably why people now use this. to explicitly say which variable you meant, if you use this practice all the time, you'll not get it wrong in the few cases where its important.
Of course, you could ensure that all member variables are uniquely named, say with a prefix like m_, but that's fallen out of fashion nowadays, people prefer to write out this.
It really depends on the situation.
http://msdn.microsoft.com/en-us/library/dk1507sz(v=vs.80).aspx
To qualify members hidden by similar names
To pass an object as a parameter to other methods
To declare indexers
As others have already pointed out, it is useful in distinguishing field/property with method variables, One other place where this is required is to invoke Extension methods on current instance. For example this.ExtensionMethod(); would work, but not just ExtensionMethod();
Other than that, its a matter of personal choice, some call it redundant and some like to use it. It totally depends on you and your team.
Personally I like to use this with class members, specially for Forms method if working on code-behind of winform, like this.Close();
For more discussion when to use this see: When do you use the "this" keyword?
I am experiencing something weird and have a workaround already, but I don't think I understood it well.
If I call the Method below numerous times within a class:
public void Method()
{
Foo a = new Foo();
a.Delegate1Handler = ViewSomething();
}
If I call Method() multiple times in one instance of the class that it is in... I am reinitializing "a" every time but for some reason a.Delegate1Handler is still around from the previous initialization, and therefore ViewSomething() is called again and again and again....
I feel like I am forgetting something critical here?
Foo's guts look like:
public delegate void Delegate1(T t);
public Delegate1 Delegate1Handler { get; set; }
EDIT: (workaround that I put in is described below, but I still don't understand exactly why it was behaving like this) ->
Initialized "a" and it's delegate1Handler outside of "Method" where delegate1Handler only gets initialized once and "a" can again get reinitialized - no problem! (or maybe it is I don't know)
a.Delegate1Handler = ViewSomething();
To me, this suggests that ViewSomething() is a method that returns a delegate.
ViewSomething() would be called every time you run Method()
I think #hans was getting at something like this in his comment
public void Method()
{
Foo a = new Foo( ViewSomething );
}
// ...
public class Foo
{
public Foo( Delegate1 del ) // note: accepting the delegate parameter
{
DelegateHandler = del;
}
}
public delegate void Delegate1(T t);
public Delegate1 Delegate1Handler { get; set; }