.Net 3.5 sp1 available type question ...
Is it possible to "get a handle" or reference to the actual instance of an assembly that called a method? I can get the executing and calling assembly via reflection, but what I'm after is not so much the assembly, but the INSTANCE of that assembly that called method.
Simple example (maybe):
interface IBob
{
int Id { get; }
void Foo();
}
public class Bob : IBob
{
private int _id = 123;
public int Id
{
get { return _id; }
}
public void Foo()
{
new OtherAssemblyClass().Bar();
}
}
public class OtherAssemblyClass
{
public void Bar()
{
//
// what I want to do here is get a reference
// to the calling INSTANCE of IBob and determine
// Bob's Id ... so something like:
//
// int Id = (System.XXX.GetCallingAssemblyInstance() as IBob).Id;
//
//
}
}
The real situation is a bit more complex than this, and precludes the obvious passing of IBob instance as a parameter in OtherAssemblyClass.Bar(), although that may be end result.
Entirely possible I'm just being stupid too, and not seeing obvious. 2 x 4 corrections to skull also welcome.
Unfortunately you can't get the instance unless it's passed in. You can find out what's calling your method by using the StackTrace.
PostSharp is the only way I would know of to make that work. Take a look at the InstanceBoundLaosEventArgs class. Warning: this is a pretty big deal, and a serious addition to the weight and complexity of your architecture, especially at build time.
I can get you halfway there if you are willing to use extension methods. Here's an example:
public static void Bar(this IBob CallingIBob)
{
int Id = CallingIBob.Id;
}
...and calling Bar():
public class Bob : IBob
{
#region IBob Members
public void Foo()
{
this.Bar();
}
public int Id
{
get { throw new NotImplementedException(); }
}
#endregion
}
Yes, it's not the exact case you were looking for, but functionally similar. Bar can be called from any bob and it will have a reference to the calling bob without explicitly passing in the instance.
I understand that you may want to call Bar in another assembly of your choice. Maybe Bar is defined in a base class and you are calling specific implementations of it in subclasses. That's ok, use the extension method to take in information about the specific Bar you are trying to access and route accordingly.
Please update your post with a more concrete problem definition if you would like a more specific solution.
Related
I'll start with a code example. I have a following class
public class Foo
{
public object DoSomething() {}
}
I also have some code that utilises method DoSomehting from class Foo.
public class Boo
{
privite Foo foo;
public void SomeMethod()
{
...
foo.DoSomething();
...
foo.DoSomething();
}
}
How could I distinguish those two calls foo.DoSomething() inside the Foo class?
What I came up with is to have an identification object passed in parameters for each call to DoSomething. Then in Foo class I would store the ids and compare them when new call is made.
public class Boo
{
privite Foo foo;
public void SomeMethod()
{
...
var idObjA = new IDObj(Guid.NewGuid());
foo.DoSomething(idObjA);
...
var idObjB = new IDObj(Guid.NewGuid());
foo.DoSomething(idObjB);
}
}
Maybe there is a better way to do it, or a pattern that I'm not aware of. I want the utilising code to be the least obscured so calls to the DoSomething method are as simple as possible.
To clarify my intentions. I'm implementing a message service with an ability for the user to check a checkbox on dialog box (e.g. Do not show again, or Apply to all). Code utilising the service can call the same method multiple times, to show an error message for example, but in different context. In other words, when user decided to not show that message again for particular action message box should not appear. Thus I need to know when method was called multiple times in the same context (action)
Maybe you should expand a bit on what exactly you are trying to achieve. If you're using your instantiated class like described above and are just trying to differentiate between the first and second call, you can add a respective toggle field in your Foo class:
public class Foo
{
private bool _firstCall = true;
public object DoSomething() {
if(_firstCall) {
_firstCall = false;
// first call logic
} else {
// second call logic
}
}
}
Based on the extra info in your edit, it sounds like what you perhaps need to be doing is setting a separate property in your Foo class showing whether the "apply to all" or "do not show again" option has been checked for a particular context.
Then when you call DoSomething, it can check that property to know if it should show the dialog or not.
So in the simplest case you might do something like:
public class Foo
{
public bool DoNotShow { get; set; };
public void DoSomething() {
if(this.DoNotShow == true) {
// logic
} else {
// alternative logic
}
}
}
public class Boo
{
privite Foo foo;
public void SomeMethod()
{
...
foo.DoSomething();
foo.DoNotShow = true;
...
foo.DoSomething();
}
}
The value could then be toggled on and off whenever you like.
N.B. You mentioned different "contexts" in which dialogs can be turned on and off.
For this, you could consider either giving this property the ability to store values for different contexts (e.g. in something like a Dictionary, perhaps) and then passing in the current context name to the DoSomething method when it's called. Or even pass in a totally separate "context" object to DoSomething each time, which contains the context name and the boolean indicating whether to show the dialog or not.
Or...using a different instance of Foo for each context might actually be more in line with object-oriented principles (in which case you could probably use the code exactly as per my example above). Again it depends exactly how the class the and the overall application works.
If knowing the line number of the call helps, you could use one of the methods for getting the caller information described here. So for example:
public class Foo
{
public object DoSomething() {
StackFrame frame = new StackFrame(1, true);
var method = frame.GetMethod();
var lineNumber = frame.GetFileLineNumber();
}
}
In my project, I have many DLL assemblies referenced. One of those DLL's contains the bool method that I want to change. I do not have the original source for the DLL and using a Reflector to decompile a project seems impractical. All I want to do is intercept or override this method or method call so that I can change it's return value to match my own method outside of said DLL.
Any such way to do this? Thanks!
Edit:
Here is an example:
public virtual bool isOwner()
{
return false;
}
Essentially, I just want to change getOwner to return true;
If the class is public and the method is marked as virtual, then you can simply override it with this syntax:
public MyClass : TheClass
{
public override ReturnType MethodName(Arguments)
{
//class the base class implementation if needed
//base.MethodName(Arguments)
//do your own stuff and return whatever is needed
}
}
Hope this helps
EDIT: A word of caution though, this won't replace the calling code within the DLL. It will only work if you instantiate the derived class yourself and call it from your code.
Is there a general way to do what you want, built into .NET?
Yes, and no.
If you want every usage of class X' method Y to be replaced by some other code, then no, there is nothing built into .NET class system or compiler that will do this.
If you can inherit from class X, overriding method Y, and then ensure that all places where class X is used, your new class is used instead, then yes, that is the proper way to do this.
This is easily done:
public class YourFixedClass : TheProblematicClass
{
public override string YourProblematicMethod()
{
// probably call the problematic method through base.
// and fix the return value, or fix the parameters
// or don't call it at all, re-doing whatever it does
}
}
Or, if you can make a new class that implements all the same interfaces, wrapping (delegating) all the methods and properties of the original (problematic) class, then that might be doable, but this requires all actual usage of the class to go through the interfaces.
As this:
public class Wrapper : IInterface1, IInterface2
{
private readonly YourProblematicClass _C;
public Wrapper(YourProblematicClass c)
{
_C = c;
}
public string YourProblematicMetho()
{
// probably call the problematic method through _C.
// and fix the return value, or fix the parameters
// or don't call it at all, re-doing whatever it does
}
}
If, on the other hand, you don't have control of where all the code is that calls the class/method, then no, you can't do any of this.
So what else is there? Well, there is always the debugger interfaces. You can make a program that is somehow the debugger of itself, patching in the right code upon demand, but this is likely to be extraordinary difficult to get right.
In short, no, there is no way to do what you want. You need to find a different way to accomplish this.
Have you thought about changing the original assembly in the first place? I understand that you don't have the source code for it, but is that because:
You lost it
You didn't make it
In point 1, I would really work towards recreating the source code, either through a decompiler or similar, and get a new project going to fix that.
In point 2, have you thought about contacting the people that made it and asking them for help?
Uhm Ok you can do something like this:
public class MyNameClass : MyDllname.MyClassName
{
public bool isOwner()
{
return !base.isOwner();
}
}
Then you have override the method and you can use all the other methods in the DLL simply using an istance(if there aren't static) of the MyNameClass
You can use "new" modifier.
See example on http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
Or this:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new ClassA().IsEvenDayToday()); // Result: true
Console.WriteLine(new ClassB().IsEvenDayToday()); // Result: false
Console.ReadKey();
}
}
public class ClassA : ClassB
{
public new bool IsEvenDayToday()
{
return DateTime.Now.Day % 2 == 0;
}
}
public class ClassB
{
public bool IsEvenDayToday()
{
return DateTime.Now.Day % 2 != 0;
}
}
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?
In the code below I tried in two ways to access the parent version of methodTwo, but the result was always 2. Is there any way to get the 1 result from a ChildClass instance without modifying these two classes?
class ParentClass
{
public int methodOne()
{
return methodTwo();
}
virtual public int methodTwo()
{
return 1;
}
}
class ChildClass : ParentClass
{
override public int methodTwo()
{
return 2;
}
}
class Program
{
static void Main(string[] args)
{
var a = new ChildClass();
Console.WriteLine("a.methodOne(): " + a.methodOne());
Console.WriteLine("a.methodTwo(): " + a.methodTwo());
Console.WriteLine("((ParentClass)a).methodTwo(): "
+ ((ParentClass)a).methodTwo());
Console.ReadLine();
}
}
Update ChrisW posted this:
From outside the class, I don't know
any easy way; but, perhaps, I don't
know what happens if you try
reflection: use the Type.GetMethod
method to find the MethodInfo
associated with the method in the
ParentClass, and then call
MethodInfo.Invoke
That answer was deleted. I'm wondering if that hack could work, just for curiosity.
Inside of ChildClass.methodTwo(), you can call base.methodTwo().
Outside of the class, calling ((ParentClass)a).methodTwo() will call ChildClass.methodTwo. That's the whole reason why virtual methods exist.
At the IL level, you could probably issue a call rather than a callvirt, and get the job done - but if we limit ourselves to C# ;-p (edit darn! the runtime stops you: VerificationException: "Operation could destabilize the runtime."; remove the virtual and it works fine; too clever by half...)
Inside the ChildClass type, you can use base.methodTwo() - however, this is not possible externally. Nor can you go down more than one level - there is no base.base.Foo() support.
However, if you disable polymorphism using method-hiding, you can get the answer you want, but for bad reasons:
class ChildClass : ParentClass
{
new public int methodTwo() // bad, do not do
{
return 2;
}
}
Now you can get a different answer from the same object depending on whether the variable is defined as a ChildClass or a ParentClass.
As mentioned above, something is bad with your class design if you need to call "base.base" in PRODUCTION code. But it is quite legitimate to use this technique if you are debugging or searching some workarrounds while using external libraries you cannot compile. It is unpleasant that C# does not provide this option directly. Still you may use Kenneth Xu solution with IL generator and Emit. It works.
class A { public virtual string foo() { return "A"; } }
class B : A { public override string foo() { return "B"; } }
// now in class C
class C : B {}
// we can call virtual method "foo" from A using following code
MethodInfo fooA = typeof(A).GetMethod("foo", BindingFlags.Public | BindingFlags.Instance);
DynamicMethod baseBaseFoo = new DynamicMethod(
"foo_A",
typeof(string),
new[] { typeof(A) },
typeof(A));
ILGenerator il = baseBaseFoo.GetILGenerator();
il.Emit(OpCodes.Ldarg, 0);
il.EmitCall(OpCodes.Call, fooA, null);
il.Emit(OpCodes.Ret);
// call foo() from class A, it returns "A"
(string)baseBaseFoo.Invoke(null, new object[] { this });
For reference and a complete sample see
http://kennethxu.blogspot.cz/2009/05/cnet-calling-grandparent-virtual-method.html
Thank you Kenneth Xu!
As Mark Gravell said, no, not externally. But here's another hack I have used. ChildClass can expose methodTwo() from the ParentClass for its own use or for external use. In your case:
class ChildClass : ParentClass {
override public int methodTwo() {
return 2;
}
public int ParentClass_methodTwo() {
return base.methodTwo();
}
}
// Now instead of
Console.WriteLine("ParentClass methodTwo: " + ((ParentClass)a).methodTwo());
// use
Console.WriteLine("ParentClass methodTwo: " + a.ParentClass_methodTwo());
In my case, the child class introduced the concept of a Peer, and I needed its override of methodTwo() to invoke the base version on the peer. By overridding it, however, it hid it... Or did it? This technique came to the rescue.
class ChildClass : ParentClass {
ChildClass peer;
override public int methodTwo() {
return peer.ParentClass_methodTwo();
}
private int ParentClass_methodTwo() {
return base.methodTwo();
}
}
To my knowledge, once a method has been overridden then you can't call the parent method.
public class Parent
{
public string Method()
{
return "parent";
}
}
public class Child:Parent
{
public string Method()
{
return "child";
}
}
Above code successfully overrides parent method yet value of parent method still unchanged.
You can return values from the Both Parent class and Child class using code below -
Child child = new Child();
string result = (((Parent)child).Method()) + child.Method();
But Visual Studio will show you a warning in Compile Time.
I would think that it is not possible unless you make instance of the ParentClass directly.
Thats the very essense of inheritance, polymorphism...
I stumbled upon this looking for help and ended up with my own approach to calling ancestor versions of a method. This is more of a work-around which assumes you can edit the ancestor class:
Put the functionality in question in the ancestor class into a static method, with the necessary parameters. The method in that class can call it so it need not duplicate the functionality, and the child class can call to that functionality if desired via the static method. That way, it can be done even within a method and can cite which specific class it wants to invoke. Also, it can access farther back ancestors than mere parents, which is the limitation of use "base".
All I need is a way to make a property of one class only 'settable' from one other class (a sort of manager class).
Is this even possible in c#?
My colleague 'reliably' informs me that I have a design flaw, but I feel I should at least ask the community before I concede defeat!
No, it's not really possible to do this in any clean way in C#. You probably have a design flaw ;-)
You can use the internal modifier, which lets all types in the same assembly access the data (or nominated assemblies if using [InternalsVisibleTo] - but no: there is no friend equivalent in C#.
For example:
public string Foo {get; internal set;}
You have a design flaw. Also, don't be paranoid about data hiding. Here's 3.5's way to do it:
class Program
{
static void Main(string[] args)
{
Managed m = new Managed();
Console.WriteLine(m.PrivateSetter);
m.Mgr.SetProperty("lol");
Console.WriteLine(m.PrivateSetter);
Console.Read();
}
}
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(s => PrivateSetter = s)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
}
public class Manager
{
private Action<string> _setPrivateProperty;
public Manager(Action<string> setter)
{
_setPrivateProperty = setter;
}
public void SetProperty(string value)
{
_setPrivateProperty(value);
}
}
Here's how we'd do it in pre-lambda days:
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(this)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
public class Manager
{
public void SetProperty(string value)
{
m.PrivateSetter = value;
}
private Managed m;
public Manager(Managed man)
{
m = man;
}
}
}
The best way to do it would be:
/// <summary>
/// Gets or sets foo
/// <b>Setter should only be invoked by SomeClass</b>
/// </summary>
public Object Foo
{
get { return foo; }
set { foo = value; }
}
When you have some complex access or inheritance restriction, and enforcing it demands too much complexity in the code, sometimes the best way to do it is just properly commenting it.
Note however that you cannot rely on this if this restriction has some security implications, as you are depending on the goodwill of the developer that will use this code.
You cannot do that on that way, but you can access a property's setter method from a derived class, so you can use inheritance for the purpose. All you have to do is to place protected access modifier. If you try to do so, your colleague is right :). You can try doing it like this:
public string Name
{
get{ return _name; }
protected set { _name = value; }
}
keep in mind that the set method of the property is only accessible from the derived class.
Or you could have these two classes in an assembly alone and have the setter as internal. I would vote up for the design flaw though, unless the previous answer by milot (inheriting and protected) makes sense.
You could do:
public void setMyProperty(int value, Object caller)
{
if(caller is MyManagerClass)
{
MyProperty = value;
}
}
This would mean that you could use a 'this' pointer from the calling class. I would question the logic of what you're attempting to achieve, but without knowing the scenario I can't advise any futher. What I will say is this: if it is possible to refactor your code to make it clearer, then it is often worthwhile doing so.
But this is pretty messy and certinly NOT fool-proof ... you have been warned!
Alternativly...
You could pass a delegate from the Class with the Property (Class A) to the Manager Class (Class B). The delegate can refer to a private function within A to allow B to call that delegate as any normal function. This precludes that A knows about B and potentially that A is created before B. Again... messy and not fool-proof!
You can achieve to this by making a Public property in your "settable class" that will inherit from the real class that will have a protected property... this way only the inherit class can SET and not class that doesn't inherit. But the drawback is that you will require to have an inherit class...
Reflection, though I would agree that having to do this just to get around an access modifier is probably an indication of a bad design.
public class Widget
{
private int count;
public int Count
{
get { return this.count; }
private set { this.count = value; }
}
}
public static class WidgetManager
{
public static void CatastrophicErrorResetWidgetCount( Widget widget )
{
Type type = widget.GetType();
PropertyInfo info = type.GetProperty("Count",BindingFlags.Instance|BindingFlags.NonPublic);
info.SetValue(widget,0,null);
}
}
The reason this is a design flaw is because it seems muddled between the scope of the two objects.
The properties of a class should be accessible in the context of that class, at least internally.
It sounds like the settable property on your item class is really a property of the manager class.
You could do something similar to what you want by closely coupling the two classes:
public class MyItem {
internal MyItemManager manager { get;set; }
public string Property1 {
get { return manager.GetPropertyForItem( this ); }
}
}
Unfortunately this isn't great design either.
What your looking for is what C++ calls a Friend class but neither c# or vb has this functionality. There is a lot of debate as to the merit of such functionality since it almost encourages very strong coupling between classes. The only way you could implement this in c# would be with reflection.
If your goal is to have a class Foo let some property (e.g. Bar, of type Biz) to be changed by some other object, without exposing it publicly, a simple way to do that is to have an instance of Foo which is supposed to be changeable by some other object to pass that other object an Action<Biz> which points to a private method that changes Bar to the passed-in value. The other object may use that delegate to change the Bar value of the object that supplied it.
If one wishes to have give all instances of some type Woozle the ability to set the Bar value of any instance of Foo, rather than exposing such abilities on a per-instance basis, one may require that Woozle have a public static method Woozle.InstallFooBarSetter which takes a parameter of type Action<Foo, Biz> and one of type Object. Foo should then have a static method WoozleRequestBarSetter which takes an Object, and passes it to Woozle.InstallFooBarSetter along with an Action<Foo,Biz>. The class initializer for Woozle should generate a new Object, and pass it to Foo.RequestBarSetter; that will pass the object to Woozle.InstallFooBarSetter along with a delegate. Woozle can then confirm that the passed-in object is the one that it generated, and--if so--install the appropriate delegate. Doing things this way will ensure that nobody but Woozle can get the delegate (since the delegate is only passed to Woozle.InstallFooBarSetter), and Woozle can be sure its delegate comes from Foo (since nobody else would have access to the object that Woozle created, and Woozle.InstallFooBarSetter won't do anything without it).
if it is a design flaw depends on what you want to do. You could use the StackTrace class from System.Diagnostics to get the Type of the class setting your property and then compare to the type you want to allow setting yor property..but maybe there are better ways for performing something like this (e.g. boxing)