While I'm testing the Castle DynamicProxy I found an weird behavior
I didn't found good documentation, so the closer information I found was theses 2 ask
Castle Dynamic Proxy not intercepting method calls when invoked from within the class
and
Why won't DynamicProxy's interceptor get called for *each* virtual method call?
and with it, I suppose that, when you use the CreateClassProxyWithTarget everything goes into the Class and back to the proxy, so if the Prop/function is not virtual, it only return the Class value.
I guess, with code sample, my question get clear.
Let's suppose I have this code
Main
private static void Main(string[] args)
{
var theObj = new SomeClass
{
NonVirtualString = "Non virtual value",
VirtualString = "Virtual value"
};
var theProxy = Interceptor.AddProxy(theObj);
Console.WriteLine($"OBJ NonVirtualString: {theObj.NonVirtualString } || VisrtualString {theObj.VirtualString }");
Console.WriteLine($"Proxy NonVirtualString: {theProxy.NonVirtualString } || VisrtualString {theProxy.VirtualString }");
}
public class SomeClass
{
public string NonVirtualString { get; set; }
public virtual string VirtualString { get; set; }
}
Interceptor
public static class Interceptor
{
private static readonly ProxyGenerator _generator = new ProxyGenerator();
public static TEntity AddProxy<TEntity>(TEntity entity) where TEntity: class, new()
{
var proxy = _generator.CreateClassProxyWithTarget(entity, new LogInterceptor());
return proxy;
}
}
Logger
[Serializable]
public class LogInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
try
{
invocation.Proceed();
Console.WriteLine("Intercepting: {0} with value: {1}", invocation.Method.Name, invocation.ReturnValue);
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Exception in method {0}{1}{2}", invocation.Method.Name,
Environment.NewLine, ex.Message));
throw;
}
}
}
the result is
OBJ NonVirtualString: Non virtual value || VisrtualString Virtual value
Intercepting: get_VirtualString with value: Virtual value
Proxy NonVirtualString: NULL || VisrtualString Virtual value
And the expected result would be
OBJ NonVirtualString: Non virtual value || VisrtualString Virtual value
Intercepting: get_VirtualString with value: Virtual value
Proxy NonVirtualString: Non virtual value || VisrtualString Virtual value
So, if the result is right, how I can do, with Castle or other Lib what I'm trying(Only overhide the virtual and keep the non virtual accessible ?
You probably can't. Not with the composition-based CreateClassProxyWithTarget, anyway. When you are calling a non-virtual method on such a proxy object, you're completely bypassing DynamicProxy; it cannot intercept that invocation and therefore won't forward it to the target object. Thus you get back the value of the proxy object's own uninitialized NonVirtualString property.
You could get this to work with inheritance-based proxying, i.e. with CreateClassProxy. Using that approach, you'll only have one object (the proxy) instead of two, so you'd set the property values directly on the proxy object instead of on a separate target. Then, even though DynamicProxy still won't be able to intercept the call to NonVirtualString's getter, the call will just use the original class' getter.
Because the property is not virtual the proxy class cannot override it. When you call Interceptor.AddProxy() it creates a new object of type that inherits from SomeClass. This object will have its own values of VirtualString and NonVirtualString. VirtualString Will be overridden by the library to use Interceptor, but NonVirtualString will not be overriden and will remain NULL, as it's the default for string.
You might try to use Interface interception instead. Otherwise, you won't be able to intercept a non virtual methods/properties.
Related
Yeah. Talk about confusing titles. So this is the scenario: I've a generic class PromiseListener which looks like this:
public class PromiseListener<T>
{
public virtual void IsResovled(T value)
{
return;
}
public virtual void IsSpoiled()
{
return;
}
}
This class is supposed to be implemented and its methods overridden. An implementation of this class may look like this:
public class TestPromiseListener : PromiseListener<float>
{
public override void IsResovled(float value)
{
System.Diagnostics.Debug.WriteLine("RMI RETURNED VALUE " + value);
}
}
This TestPromiseListener is what's implemented by users. What I need to do is store listeners in a dictionary (key is irrelevant for this problem). This is the context of the problem: a promise is an unresolved return-value of a remote method which may eventually resolve to an actual value. A promise is immediately returned when a remote method invocation is made. So then you can "install" a PromiseListener whose methods have been implemented by a derived class (TestPromiseListener). One of these methods is IsResovled which takes one argument: the return value of the remote method invocation. This method would be called when the remote method invocation finally returns a value.
I'm having trouble storing the objects in a dictionary. I could store the listeners as object, but I don't see how I could get a listener from the dictionary without knowing the type first, because I would need to know its original type to cast it to. When fetching the PromiseListener I only know the type of the return value (and all information to fetch the right listener from a dictionary). So what I'm asking is: is there a type-safe way to store these generic objects, fetch them and call their methods?
(Some more detailed info as requested - sorry for the wall of text)
Both IsResolved and IsSpoiled may be called at different times. A promise can resolve if a return value has been received (calls IsResolved) or it may be spoiled when no return value could be received (due to a network error, for example) (calls IsSpoiled). The PromiseListener a user implements may choose to override any of these methods. So internally I have a method which is called when a return value has been received from the network. In this method I have the identifier for the listener (key in the mentioned dictionary), the actual return value (object) and the AssemblyQualifiedName of the return value (which I can use to convert the return value of type object to the correct type). I'll then have to find the correct listener - which I can because I have its identifier - but I don't know how to fetch it in a type-save way because I don't know what type the listener is supposed to be.
?Type? listener; // Don't know what type the listener is. Could be PromiseListener<string> or PromiseListener<int> - or anything, really
if(promiseManager.TryGetPromiseListener(promise, out listener)
...
Is there some reason why you can't use a non-generic base class?
public abstract class PromiseListenerBase
{
public abstract Type PromisedType { get; }
public abstract void HandleResolution(object value);
}
public class PromiseListener<T> : PromiseListenerBase
{
public override Type PromisedType
{
get { return typeof(T); }
}
public override void HandleResolution(object value)
{
T val = (T)value;
this.IsResolved(val);
}
public virtual void IsResolved(T value) { /* some logic */ }
public virtual void IsSpoiled() { /* some logic */ }
}
public class FloatListener : PromiseListener<float>
{
public override void IsResolved(float value)
{
Console.Out.WriteLine("FloatListener value {0}", value);
}
}
public class IntListener : PromiseListener<int>
{
public override void IsResolved(int value)
{
Console.Out.WriteLine("IntListener value {0}", value);
}
}
public class SomethingUsingPromiseListeners
{
public void SomeMethod()
{
Dictionary<string, PromiseListenerBase> listeners =
new Dictionary<string, PromiseListenerBase>();
listeners.Add("float", new FloatListener());
listeners.Add("int", new IntListener());
int someValue = 123;
foreach (PromiseListenerBase listener in listeners.Values)
{
if (listener.PromisedType == someValue.GetType())
{
listener.HandleResolution(someValue);
}
}
}
}
I'm testing an MVC controller which relies on a value returned from a read-only property on the base class.
The getter for this property throws an exception when it is called as it is relies on a HttpContext (and other nasty stuff) which I would rather avoid mocking.
This is what I've tried so far:
controller = Substitute.ForPartsOf<MyController>(
Substitute.For<SomeDependency>(),
);
controller.UserInfo.Returns(new UserInfo());
Yet this throws an exception as soon as UserInfo is accessed.
Property on base class is:
public UserInfo UserInfo
{
get
{
// HttpContext dependent stuff
}
}
I've tried setting the base class property to virtual but then I get a Castle proxy exception.
I think you may be having another problem. NSubstitute is capable of handling substitution of virtual properties. Here is a small program that illustrates
public class SubstitutedClass
{
public virtual int SubstitutedProperty { get { throw new InvalidOperationException(); } }
}
internal class Program
{
private static void Main(string[] args)
{
var test2 = Substitute.For<SubstitutedClass>();
test2.SubstitutedProperty.Returns(10);
Console.WriteLine(test2.SubstitutedProperty);
}
}
EDIT: Regarding your use of ForPartsOf I don't think it is possible to override a property this way, since there is no way of informing NSubstitute that we don't want it to call the base code. That's why the documentation mentions that partial sub are not recommended
You could change the base class in order to return the value of a virtual function; this virtual function would then be substituted. No signature change for the callers. Although this is a hack you would get what you need
public class SubstitutedClass
{
public virtual int SubstitutedProperty { get { return InnerValue(); } }
public virtual int InnerValue() { throw new InvalidOperationException(); }
}
var test2 = Substitute.ForPartsOf<SubstitutedClass>();
test2.When(t => t.InnerValue()).DoNotCallBase();
test2.InnerValue().Returns(10);
I want to force subclasses to define a constant value.
Like
const string SomeConstantEverySubclassMustDefine = "abc";
I need that because I need to have it tied to the Type, rather than to the instance and you can't override static Methods/Properties iirc.
I'd really like to have a compile-time check for those constants.
Let me explain in more detail:
Some classes in our Domain-Model are special, you can take certain actions for them, depending on the type. Thus the logic is tied to the type. The action to be taken requires a string tied to the type. I sure could create an instance everytime as a workaround and declare an abstract property, but that's not what I want. I want to enforce the declaration of the string at compile-time, just to be sure.
No, you can't. I would suggest you make your base class abstract, with an abstract property which you can fetch when you want. Each child class can then implement the property just by returning a constant if it wants. The downside is that you can't use this within static methods in the base class - but those aren't associated with the child classes anyway.
(It also allows child classes to customise the property per instance as well, if necessary... but that's rarely an actual problem.)
If this doesn't do enough for you, you might want to consider a parallel type hierarchy. Basically polymorphism simply doesn't happen in a type-specific way in .NET; only in an instance-specific way.
If you still want to do this and fetch it with reflection, I suggest you just write unit tests to ensure that the relevant constants are defined. When you get beyond what the type system can describe, that's often the best you can do.
Make an abstract property with only a get. That's what I think you could do to enforce a class has a value. Then you can just return a constant in the property.
Example:
Base class:
public abstract string MyConst { get; }
Derived class:
public override string MyConst {
get { return "constant"; }
}
Here is how I made mine work. I used Attribute as others have suggested.
public class ObjectAttribute : Attribute
{
public int ObjectSize { get; set; }
public ObjectAttribute(int objectSize)
{
this.ObjectSize = objectSize;
}
}
public abstract class BaseObject
{
public static int GetObjectSize<T>() where T : IPacket
{
ObjectAttribute[] attributes = (ObjectAttribute[])typeof(T).GetCustomAttributes(typeof(ObjectAttribute), false);
return attributes.Length > 0 ? attributes[0].ObjectSize : 0;
}
}
[ObjectAttribute(15)]
public class AObject : BaseObject
{
public string Code { get; set; }
public int Height { get; set; }
}
[ObjectAttribute(25)]
public class BObject : BaseObject
{
public string Code { get; set; }
public int Weight { get; set; }
}
If you would like instance access to the attribute just add it to the base abstract class.
public abstract class BaseObject
{
public static int GetObjectSize<T>() where T : IPacket
{
ObjectAttribute[] attributes = (ObjectAttribute[])typeof(T).GetCustomAttributes(typeof(ObjectAttribute), false);
return attributes.Length > 0 ? attributes[0].ObjectSize : 0;
}
public int ObjectSize
{
get
{
ObjectAttribute[] attributes = (ObjectAttribute[])GetType().GetCustomAttributes(typeof(ObjectAttribute), false);
return attributes.Length > 0 ? attributes[0].ObjectSize : 0;
}
}
}
Usage of the constants
int constantValueA = AObject.GetObjectSize<AObject>();
int constantValueB = BObject.GetObjectSize<BObject>();
AObject aInstance = new AObject();
int instanceValueA = aInstance.ObjectSize;
New idea
Here's a sort of weird idea: instead of using inheritance directly, you create a separate class to provide a constant value for every type deriving from some type T. The constructor for this type uses reflection to verify that every derived type has indeed been supplied a value.
public abstract class Constant<T, TConstant>
{
private Dictionary<Type, TConstant> _constants;
protected Constant()
{
_constants = new Dictionary<Type, TConstant>();
// Here any class deriving from Constant<T, TConstant>
// should put a value in the dictionary for every type
// deriving from T, using the DefineConstant method below.
DefineConstants();
EnsureConstantsDefinedForAllTypes();
}
protected abstract void DefineConstants();
protected void DefineConstant<U>(TConstant constant) where U : T
{
_constants[typeof(U)] = constant;
}
private void EnsureConstantsDefinedForAllTypes()
{
Type baseType = typeof(T);
// Here we discover all types deriving from T
// and verify that each has a key present in the
// dictionary.
var appDomain = AppDomain.CurrentDomain;
var assemblies = appDomain.GetAssemblies();
var types = assemblies
.SelectMany(a => a.GetTypes())
.Where(t => baseType.IsAssignableFrom(t));
foreach (Type t in types)
{
if (!_constants.ContainsKey(t))
{
throw new Exception(
string.Format("No constant defined for type '{0}'.", t)
);
}
}
}
public TConstant GetValue<U>() where U : T
{
return _constants[typeof(U)];
}
}
Basic example:
public class BaseType
{
public static Constant<BaseType, string> Description { get; private set; }
static BaseType()
{
Description = new BaseTypeDescription();
}
}
public class DerivedType : BaseType
{ }
internal sealed class BaseTypeDescription : Constant<BaseType, string>
{
public BaseTypeDescription() : base()
{ }
protected override DefineConstants()
{
DefineConstant<BaseType>("A base type");
DefineConstant<DerivedType>("A derived type");
}
}
Now I have code that allows me to do this:
var description = BaseType.Description;
// returns "A base type"
string baseTypeDescription = description.GetValue<BaseType>();
// returns "A derived type"
string derivedTypeDescription = description.GetValue<DerivedType>();
Original answer
You may not like it, but the closest way to accomplish this is by declaring an abstract read-only (no set) property.
If you've got an instance of your subclass, then this can work just as well as a constant, even though it is technically instance-level (it will just be the same for all instances of the given class).
Consider, for instance, IList.IsReadOnly. In most cases this is actually a property that tells you about the underlying class implementation, as opposed to any state specific to a particular instance. (It may be an interface member as opposed to an abstract class member, but it's the same idea.)
If you are trying to access it statically, well... then you're out of luck. But in this case I fail to see how you'd obtain the value without using reflection anyway. Maybe that's your intention; I don't know.
You could have a static method in the base class called, for instance "Register", that is passed a Type and a constant value, with the intention being that it is called by the class constructors of the subtypes. Then, add a check in all of your base class constructors that the object being constructed is of a registered type.
abstract class Base
{
private static Dictionary<Type, string> _registry = new Dictionary<Type, string>();
protected static void Register(Type t, string constVal)
{
_registry.Add(t, constVal);
}
protected Base()
{
if(!_registry.ContainsKey(this.GetType()))
throw new NotSupportedException("Type must have a registered constant");
}
public string TypeConstant
{
get
{
return _registry[this.GetType()];
}
}
}
class GoodSubtype : Base
{
static GoodSubtype()
{
Base.Register(typeof(GoodSubtype), "Good");
}
public GoodSubtype()
: base()
{
}
}
class Badsubtype : Base
{
public Badsubtype()
: base()
{
}
}
And then elsewhere, you can construct GoodSubtype instances, but trying to construct a Badsubtype gets an exception. I think a runtime error at construction is the soonest you can get an error with this type of scheme.
(You'd want to use ConcurrentDictionary for your registry if threading is involved)
There's one other method that hasn't been covered and it uses the new modifier to hide consts values in the base class. In a way, it's similar to Nap's solution, but doesn't allow per-instance access and therefore doesn't allow for polymorphic access within the base class. This solution is only useful if you want to have constant value defined but wish to have the option of changing it to different values in different subclasses.
static void Main(string[] args)
{
Console.WriteLine("BaseClass.MyConst = {0}, ClassA.MyConst = {1}, ClassB.MyConst = {2}", BaseClass.MyConst, ClassA.MyConst, ClassB.MyConst);
Console.ReadKey();
}
class BaseClass
{
public const int MyConst = 1;
}
class ClassA : BaseClass
{
public new const int MyConst = 2;
}
class ClassB : BaseClass
{
}
Edit: Changed question title from "Does C# allow method overloading, PHP style (__call)?" - figured out it doesn't have much to do with actual question. Also edited question text.
What I want to accomplish is to proxy calls to a an instance of an object methods, so I could log calls to any of its methods.
Right now, I have code similar to this:
class ProxyClass {
static logger;
public AnotherClass inner { get; private set; }
public ProxyClass() { inner = new AnotherClass(); }
}
class AnotherClass {
public void A() {}
public void B() {}
public void C() {}
// ...
}
// meanwhile, in happyCodeLandia...
ProxyClass pc = new ProxyClass();
pc.inner.A(); // need to write log message like "method A called"
pc.inner.B(); // need to write log message like "method B called"
// ...
So, how can I proxy calls to an object instance in extensible way? Method overloading would be most obvious solution (if it was supported in PHP way). By extensible, meaning that I don't have to modify ProxyClass whenever AnotherClass changes.
In my case, AnotherClass can have any number of methods, so it wouldn't be appropriate to overload or wrap all methods to add logging.
I am aware that this might not be the best approach for this kind of problem, so if anyone has idea what approach to use, shoot.
Thanks!
Echoing the two other; DI is the way to go. Dynamic Proxy is very competent in this respect.
Here is some example code, complete with implementation of all that is required. Normally it's good practice to code against an interface.
I can recommend reading a bit about AOP, here's my thread on it:
Help and Information about Aspect Oriented Programming
(Edit: Becuase you were nice and gave me some points, here's another cool link to a DP tutorial that's really well done: http://kozmic.pl/archive/2009/04/27/castle-dynamic-proxy-tutorial.aspx ;))
Here is example code:
using System;
using System.Collections.Generic;
using Castle.Core;
using Castle.Core.Interceptor;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using NUnit.Framework;
[TestFixture]
public class LoggingMethodInvocationsTests
{
[Test]
public void CanLogInvocations()
{
var container = new WindsorContainer();
container.Register(Component.For<LoggingInterceptor>().LifeStyle.Singleton);
// log all calls to the interface
container.Register(Component.For<IA>().ImplementedBy<A>().Interceptors(typeof (LoggingInterceptor)));
var a = container.Resolve<IA>();
a.AMethod(3.1415926535); // to interface
Console.WriteLine("End of test");
}
}
public class LoggingInterceptor : IInterceptor, IOnBehalfAware
{
private string _entityName;
public void Intercept(IInvocation invocation)
{
var largs = new List<string>(invocation.Arguments.Length);
for (int i = 0; i < invocation.Arguments.Length; i++)
largs.Add(invocation.Arguments[i].ToString());
var a = largs.Count == 0 ? "[no arguments]" : string.Join(", ", largs.ToArray());
var method = invocation.Method == null ? "[on interface target]" : invocation.Method.Name;
Console.WriteLine(string.Format("{0}.{1} called with arguments {2}", _entityName, method, a));
invocation.Proceed();
Console.WriteLine(string.Format("After invocation. Return value {0}", invocation.ReturnValue));
}
public void SetInterceptedComponentModel(ComponentModel target)
{
if (target != null)
_entityName = target.Implementation.FullName;
}
}
public class A : IA
{
public double AMethod(double a)
{
Console.WriteLine("A method impl");
return a*2;
}
public void SecondMethod(double a)
{
Console.WriteLine(string.Format("Impl: SecondMethod called with {0}", a));
}
}
public interface IA
{
double AMethod(double a);
}
Console output
Examples.A.AMethod called with arguments 3,1415926535
A method impl
After invocation. Return value 6,283185307
End of test
I have use a number of solutions to not quite this problem, but similar things.
1- You could derive a custom proxy from RealProxy and take advantage of the call interceptio provided by the .NET remoting infrastructure. The advantage is that this is super easy, but the limitation is that you need to proxy either an interface and use reflection to invoke the members of your inner class or the class being proxied must inherit from MarshalByRrefObject.
While I hesitate to give a code sample, just because it would not be complete, and I will probably get flamed. But here is a ten minute piece of code just to get you pointed to the right classes etc. Beware, I only handle the IMethodCallMessage so this is not complete but should work as a demo.
class LoggingProxy<T> : RealProxy where T : MarshalByRefObject, new()
{
T _innerObject;
public static T Create()
{
LoggingProxy<T> realProxy = new LoggingProxy<T>();
T transparentProxy = (T)realProxy.GetTransparentProxy();
return transparentProxy;
}
private LoggingProxy() : base(typeof(T))
{
_innerObject = new T();
}
public override IMessage Invoke(IMessage msg)
{
if (msg is IMethodCallMessage)
{
IMethodCallMessage methodCall = msg as IMethodCallMessage;
System.Diagnostics.Debug.WriteLine("Enter: " + methodCall.MethodName);
IMessage returnMessage = RemotingServices.ExecuteMessage(_innerObject, msg as IMethodCallMessage);
System.Diagnostics.Debug.WriteLine("Exit: " + methodCall.MethodName);
return returnMessage;
}
return null;
}
}
This can be used as follows
class MyClass : MarshalByRefObject
{
public int Age
{
get;
set;
}
}
MyClass o = LoggingProxy<MyClass>.Create();
o.Age = 10;
The above will log the call to set_Age on the proxied instance of MyClass.
2- Another alternative, but much more work is to create a proxy class that dynamically generates a type derived from the type you pass in and provides implementations of all the methods and properties in the base type. The generated methods etc. will perform the logging call the base class implementation etc. similar to the RealProxy example. Using VS var type you can probably avoid the need to actually inherit from the type and rather use aggregation for this proxy, that way you will still have intelli-sense support and not need to make all the methods/properties virtual. Sorry no example, this is a little too much for now. But you can look at using CodeDom or better yet Reflection.Emit for the dynamic type building. The dynamic code could do something like that proposed in #tvanfosson's answer.
3- And finally you cpuld use DynamicObject to do much of the above, the disadvantage is that you will not have compile time verification of method calls and no intelli-sense. Again, here is a minimal example.
public class DynamicProxy : System.Dynamic.DynamicObject
{
private object _innerObject;
private Type _innerType;
public DynamicProxy(object inner)
{
if (inner == null) throw new ArgumentNullException("inner");
_innerObject = inner;
_innerType = _innerObject.GetType();
}
public override bool TryInvokeMember(System.Dynamic.InvokeMemberBinder binder, object[] args, out object result)
{
System.Diagnostics.Debug.WriteLine("Enter: ", binder.Name);
try
{
result = _innerType.InvokeMember(
binder.Name,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
null, _innerObject, args);
}
catch (MissingMemberException)
{
return base.TryInvokeMember(binder, args, out result);
}
finally
{
System.Diagnostics.Debug.WriteLine("Exit: ", binder.Name);
}
return true;
}
public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result)
{
System.Diagnostics.Debug.WriteLine("Enter: ", binder.Name);
try
{
result = _innerType.InvokeMember(
binder.Name,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty,
null, _innerObject, null);
}
catch (MissingMemberException)
{
return base.TryGetMember(binder, out result);
}
finally
{
System.Diagnostics.Debug.WriteLine("Exit: ", binder.Name);
}
return true;
}
public override bool TrySetMember(System.Dynamic.SetMemberBinder binder, object value)
{
System.Diagnostics.Debug.WriteLine("Enter: ", binder.Name);
try
{
_innerType.InvokeMember(
binder.Name,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
null, _innerObject, new object[]{ value });
}
catch (MissingMemberException)
{
return base.TrySetMember(binder, value);
}
finally
{
System.Diagnostics.Debug.WriteLine("Exit: ", binder.Name);
}
return true;
}
public override string ToString()
{
try
{
System.Diagnostics.Debug.WriteLine("Enter: ToString");
return _innerObject.ToString();
}
finally
{
System.Diagnostics.Debug.WriteLine("Exit: ToString");
}
}
}
Which is used something like the following
dynamic o2 = new DynamicProxy(new MyClass());
o.Age = 10;
There are a few option for rolling your own solution, alternatively you can look at some of the pre-backed solutions. Which is probably a better way to go, but this should give you some insight as to how some of the solutions have possibly been implemented.
This may be too heavyweight for your particular use case, but you may want to look into Castle Dynamic Proxy:
Dynamic Proxy
This framework allows you to dynamically create proxies for your classes at runtime, allowing you to intercept all calls and inject whatever logic you want.
The way I would go about it is using dependency injection and passing the logger instance to the class that needs to do the logging. If you had a framework, like MVC, that supports attribute-based filtering, then you could use those as well, though you might be limited in what you could log.
public class LoggedClass
{
private Logger Logger { get; set; }
public LoggerClass( Logger logger )
{
this.Logger = logger;
}
public void A()
{
this.Logger.Info( "A has been called" );
...
}
}
Or in MVC, or a suitable framework that understands attributes and can invoke them before method calls.
[Log]
public ActionResult A()
{
...
}
public class LogAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
... use context to log stuff
}
}
The last alternative, I can think of, which you've already said you don't want to use, is the Decorator pattern. In this case your proxy class and the proxied class would need to implement the same interface and you'd simply wrap the proxied class with the functionality that you wanted. Note that defining the interface -- and extending it when you need to add functionality to the logged class -- protects you from forgetting to extend your proxy to keep it in synch with the logged class. Since it implements the interface it won't compile unless it has all the interface methods.
public interface IDoSomething
{
void A();
void B();
}
public class ToLogClass : IDoSomething
{
public void A() { ... }
public void B() { ... }
}
public class LoggedClass : IDoSomething
{
private IDoSomething Inner { get; set; }
private Logger Logger { get; set; }
public Proxy( IDoSomething inner, Logger logger )
{
this.Inner = inner;
this.Logger = logger;
}
public void A()
{
this.Logger.Info( "A callsed on {0}", this.Inner.GetType().Name );
this.Inner.A();
}
}
Another option is an Aspect-Oriented framework like PostSharp:
http://www.sharpcrafters.com/
This allows you to define attributes that inject code that will be called at certain point during the method call (OnEntry, OnExit, OnException, etc.).
The big downside of this tool is that it requires you to run a post-compilation step against your binaries (the injection is not done dynamically at runtime, but during this post-compile step).
In the following example I am able to create a virtual method Show() in the inherited class and then override it in the inheriting class.
I want to do the same thing with the protected class variable prefix but I get the error:
The modifier 'virtual' is not valid
for this item
But since I can't define this variable as virtual/override in my classes, I get the compiler warning:
TestOverride234355.SecondaryTransaction.prefix'
hides inherited member
'TestOverride234355.Transaction.prefix'.
Use the new keyword if hiding was
intended.
Luckily when I add the new keyword everything works fine, which is ok since I get the same functionality, but this raises two questions:
Why I can use virtual/override for methods but not for protected class variables?
What is the difference actually between the virtual/override approach and the hide-it-with-new approach since at least in this example they offer the same functionality?
Code:
using System;
namespace TestOverride234355
{
public class Program
{
static void Main(string[] args)
{
Transaction st1 = new Transaction { Name = "name1", State = "state1" };
SecondaryTransaction st2 =
new SecondaryTransaction { Name = "name1", State = "state1" };
Console.WriteLine(st1.Show());
Console.WriteLine(st2.Show());
Console.ReadLine();
}
}
public class Transaction
{
public string Name { get; set; }
public string State { get; set; }
protected string prefix = "Primary";
public virtual string Show()
{
return String.Format("{0}: {1}, {2}", prefix, Name, State);
}
}
public class SecondaryTransaction : Transaction
{
protected new string prefix = "Secondary";
public override string Show()
{
return String.Format("{0}: {1}, {2}", prefix, Name, State);
}
}
}
Overriding a field does not really make sense. It's part of the state of the base class, and if an inheriting class wishes to change it, it should be changable in the inheriting class by giving it an appropriate visibility.
One thing you could do in your case is to set prefix in the constructor for the inheriting class:
// Base class field declaration and constructor
protected string prefix;
public Transaction()
{
prefix = "Primary";
}
// Child class constructor
public SecondaryTransaction()
{
prefix = "Secondary";
}
You can also make a property instead of a field, and make the property virtual. This will enable you to change the behavior of the getter and setter for the property in the inheriting class:
// Base class
public virtual string Prefix { get { /* ... */ } set { /* ... */ } }
// Child class
public override string Prefix { get { /* ... */ } set { /* ... */ } }
EDIT: As for your question of using a variable in a base constructor before an inheriting class has set it, one way to solve this is to define an initialization method in the base class, override it in the inheriting class, and call it from the base constructor before accessing any fields:
// Base class
public class Base
{
protected string prefix;
public Base()
{
Initialize();
Console.WriteLine(prefix);
}
protected virtual void Initialize()
{
prefix = "Primary";
}
}
// Inheriting class
public class Child : Base
{
public override void Initialize()
{
prefix = "Secondary";
}
}
EDIT 2: You also asked what the difference between virtual/override and name hiding (the new keyword on methods) is, if it should be avoided, and if it can be useful.
Name hiding is a feature that breaks inheritance in the case of hiding virtual methods. I.e., if you hide the Initialize() method in the child class, the base class will not see it, and not call it. Also, if the Initialize() method was public, external code that was calling Initialize() on a reference of the base type would be calling Initialize() on the base type.
Name hiding is useful when a method is non-virtual in a base class, and a child wants to provide a different implementation of its own. Note, however, that this is NOT the same as virtual/override. References of the base type will call the base type implementation, and references of the child type will call the child type implementation.
A static or non-virtual method or property is just a memory address (to simplify things). A virtual method or property is identified by an entry in a table. This table is dependent on the class defining the method or property.
When you override a virtual member in a derived class, you actually change the entry in the table for the derived class to point to the overriding method.
At run-time, access to such a member goes though the table, always. So the entry can be overridden by any derived class.
There is no such mechanism for fields, as they're meant to be accessed quickly.
Using 'new' on a member means that you do not want to override the entry in the table, but that you want a new member (with the same name as an existing virtual one, a bad practice if you ask me).
If you access a virtual member through a pointer to the base class, you'll never access the member defined as 'new' in the derived class, which is the difference mentioned in the second part of your question.
Rather create a property for the prefix member - this way you can set the property to virtual/abstract
Fields are used to store state for an object, they help the object encapsulate data and hide implementation concerns from others. By being able to override a field we are leaking the implementation concerns of the class to client code (including subtypes). Due to this most languages have taken the decision that one cannot define instance variables that can be overridden (although they can be public/protected... so you can access them).
You also cannot put instance variables in an interface
In your example, if you didn't override "Show" in the SecondaryTransaction class, then calling Show on an instance of SecondaryTransaction would actually be calling the method in the base class (Transaction), which would therefore use "Show" in the base class, resulting in output of:
Primary: name1, state1
Primary: name1, state1
So, depending on what method you were calling (i.e. one on the base class or the child class), the code would have a different value for "prefix" which would be a maintainability nightmare. I suspect what you probably want to/should do, is expose a property on Transaction that wraps "prefix".
You can't override a field because it's an implementation detail of the base class. You can change the value of a protected field, but by overriding it you'd essentially be saying I want to replace the field, not the value.
What I would do (if I absolutely didn't want to/couldn't use properties) :
public class Transaction
{
public string Name { get; set; }
public string State { get; set; }
protected string prefix = "Primary";
public virtual string Show()
{
return String.Format("{0}: {1}, {2}", prefix, Name, State);
}
}
public class SecondaryTransaction : Transaction
{
public SecondaryTransaction()
{
prefix = "Secondary";
}
public override string Show()
{
return String.Format("{0}: {1}, {2}", prefix, Name, State);
}
}
Edit: (As per my comment on another answer)
If you're calling down into your base class's ctor and need the value set, then you'll probably have to modify Transaction, possibly like this:
public class Transaction
{
public string Name { get; set; }
public string State { get; set; }
protected string prefix = "Primary";
// Declared as virtual ratther than abstract to avoid having to implement "TransactionBase"
protected virtual void Initialise()
{ }
public Transaction()
{
Initialise();
}
public virtual string Show()
{
return String.Format("{0}: {1}, {2}", prefix, Name, State);
}
}
public class SecondaryTransaction : Transaction
{
protected override void Initialise()
{
prefix = "Secondary";
}
public override string Show()
{
return String.Format("{0}: {1}, {2}", prefix, Name, State);
}
}
Why do you want to override a protected variable, surely all you want to do is set it to something else in the overriding class (possibly in the constructor)?
Overriding a field is a nonsense. Marking field as protected you automatically may access them in derived classes. You may override functions, properties, because it uses functions internally.
You can't because there is no use. What would you accomplish by overriding a field?
Simple:
class Animal{
public class Head {
int eye = 8;
}
Head head = new Head()
public void Test()
{
print head.eye;
DoOtherStufs();
} //8
protected virtual void DoOtherStufs()
{}
}
class Cat : Animal{
class new Head : Animal.Head
{
int mouth;
}
Head head = new Head()
protected override void DoOtherStufs()
{
print head.eye;
}
}
Cat cat = new Cat();
cat.head.eye = 9;
print cat.Test()
This will print 8 9 instead of 9 9 as expected.
I need a base class functional, but I also need a inherited class with I could manipulate (increase) the vars inside internal group classes vars. Its not possible!!