I am trying to use generics with specialization. See the code below. What I want to do is make runtime engine understand that specialization of the function is available based on type and it should use that instead of generic method. Is it possible without using keyword dynamic?
public interface IUnknown
{
void PrintName<T>(T someT);
}
public interface IUnknown<DerivedT> : IUnknown
{
//***** I am trying to make runtime engine understand that method below is
//***** specialization of void PrintName<T>(T someT);
void PrintName(DerivedT derivedT);
}
public class SoAndSo<DerivedT> : IUnknown<DerivedT>
{
public void PrintName<T>(T someT) { Console.WriteLine("PrintName<T>(T someT)"); }
public void PrintName(DerivedT derivedT) { Console.WriteLine("PrintName(DerivedT derivedT)"); }
}
public class Test
{
public static void TestIt()
{
List<IUnknown> unknowns = new List<IUnknown>();
unknowns.Add(new SoAndSo<int>());
unknowns.Add(new SoAndSo<string>());
//*** statement below should print "PrintName(DerivedT derivedT)"
unknowns[0].PrintName(10);
//*** statement below should print "PrintName<T>(T someT)"
unknowns[0].PrintName("abc");
//********** code snippet below works exactly as expected ************
dynamic d;
d = unknowns[0];
d.PrintName(10); // <=== prints "PrintName(DerivedT derivedT)"
d.PrintName("abc"); // <=== prints "PrintName<T>(T someT)"
}
}
EDIT
If there isn't any way to achieve what I want without use of keyword dynamic, could there be any elegant way to achieve casting to concrete type without huge enum\flag\switch-case?
EDIT - POSSIBLY ONE WAY OF ACHIEVING THIS
I wanted to post this as an answer but this is not really based on polymorphism or overloading so decided to put as an edit instead. Let me know if this makes sense.
public abstract class IUnknown
{
public abstract void PrintName<T>(T someT);
}
public abstract class IUnknown<DerivedT /*, DerivedType*/> : IUnknown //where DerivedType : IUnknown<DerivedT, DerivedType>
{
MethodInfo _method = null;
//***** I am trying to make runtime engine understand that method below is
//***** specialization of void PrintName<T>(T someT);
public override sealed void PrintName<T>(T derivedT)
{
bool isSameType = typeof(T) == typeof(DerivedT);
if (isSameType && null == _method)
{
//str = typeof(DerivedT).FullName;
Type t = GetType();
_method = t.GetMethod("PrintName", BindingFlags.Public |
BindingFlags.Instance,
null,
CallingConventions.Any,
new Type[] { typeof(T) },
null);
}
if (isSameType && null != _method)
{
_method.Invoke(this, new object[] { derivedT });
}
else
{
PrintNameT(derivedT);
}
}
public virtual void PrintNameT<T>(T derivedT)
{
}
public virtual void PrintName(DerivedT derivedT) { Console.WriteLine("PrintName(DerivedT derivedT)"); }
//public static DerivedType _unknownDerivedInstance = default(DerivedType);
}
public class SoAndSo<DerivedT> : IUnknown<DerivedT> //, SoAndSo<DerivedT>>
{
//static SoAndSo() { _unknownDerivedInstance = new SoAndSo<DerivedT>(); }
public override void PrintNameT<T>(T someT) { /*Console.WriteLine("PrintNameT<T>(T someT)");*/ }
public override void PrintName(DerivedT derivedT) { /*Console.WriteLine("PrintName(DerivedT derivedT)");*/ }
}
public static class Test
{
public static void TestIt()
{
List<IUnknown> unknowns = new List<IUnknown>();
unknowns.Add(new SoAndSo<int>());
unknowns.Add(new SoAndSo<float>());
//*** statement below should print "PrintName(DerivedT derivedT)"
unknowns[0].PrintName(10);
//*** statement below should print "PrintName<T>(T someT)"
unknowns[0].PrintName(10.3);
//*** statement below should print "PrintName(DerivedT derivedT)"
unknowns[1].PrintName(10);
//*** statement below should print "PrintName<T>(T someT)"
unknowns[1].PrintName(10.3f);
System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
for (int i = 0; i < 1000000; ++i)
{
unknowns[0].PrintName(10.3);
}
stopWatch.Stop();
System.Diagnostics.Trace.TraceInformation("Milliseconds: {0}", stopWatch.ElapsedMilliseconds);
//********** code snippet below works exactly as expected ************
dynamic d;
d = unknowns[0];
d.PrintName(10); // <=== prints "PrintName(DerivedT derivedT)"
d.PrintName("abc"); // <=== prints "PrintName<T>(T someT)"
}
Thanks in advance,
-Neel.
I don't believe there's any way of doing this. It's simply not part of the execution-time dispatch mechanism which the CLR supports. You could write this, of course:
public void PrintName<T>(T someT)
{
// This is assuming you want it based on the type of T,
// not the type of the value of someT
if (typeof(DerivedT).IsAssignableFrom(typeof(T))
{
PrintName((DerivedT)(object) someT);
return;
}
Console.WriteLine("PrintName<T>(T someT)");
}
... but that's not terribly pleasant.
You could achieve this with an explicit implementation of IUnknown<DerivedT>. However, I'm not sure this is what you are looking for.
public class SoAndSo<DerivedT> : IUnknown<DerivedT>
{
public void PrintName<T>(T someT) { Console.WriteLine("PrintName<T>(T someT)"); }
void IUnknown<DerivedT>.PrintName(DerivedT derivedT) { Console.WriteLine("PrintName(DerivedT derivedT)"); }
}
public class Test
{
public static void TestIt()
{
List<IUnknown> unknowns = new List<IUnknown>();
unknowns.Add(new SoAndSo<int>());
unknowns.Add(new SoAndSo<string>());
//*** statement below should print "PrintName(DerivedT derivedT)"
(unknowns[0] as IUnknown<int>).PrintName(10);
//*** statement below should print "PrintName<T>(T someT)"
unknowns[0].PrintName("abc");
}
}
I would suggest defining a generic static class NamePrinter<T>, with an Action<T> called PrintName, which initially points to a private method that checks whether T is a special type and either sets PrintName to either a specialized version or the non-specialized version (the non-specialized version could throw an exception if desired), and then invokes the PrintName delegate. If one does that, the first time one calls NamePrinter<T>.PrintName(T param) for any particular T, code will have to inspect type T to determine which "real" method to use, but future calls will be dispatched directly to the proper routine.
Related
I have interface that defines value and few operations:
public interface IValue<T>
{
T Value { get; }
void InteractionA(IValue<T> target);
void InteractionB(IValue<T> target);
bool Check(IValue<T> target);
}
Then i implement class based on that interface
public class DoubleValue : IValue<double>
{
public double Value { get; private set; }
public bool Check(IValue<double> target)
{
// ...
return false;
}
public void InteractionA(IValue<double> target)
{
// ...
}
public void InteractionB(IValue<double> target)
{
// ...
}
}
Now i want to make universal manipulator that operates on pool of values and uses generics (so i only write it once). Because of the way i want to use this class in the future it cannot be declared static. Moving generic type into methods also doesn't do any good.
The closest i could get is:
public class ValueManipulator<T>
{
public IEnumerable<IValue<T>> Pool { get; private set; }
public ValueManipulator(IEnumerable<IValue<T>> pool)
{
Pool = pool;
}
public void ManipulateA()
{
foreach (int i in Enumerable.Range(0, Pool.Count()))
{
IValue<T> firstValue = Pool.ElementAt(i);
foreach (IValue<T> secondValue in Pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
public void ManipulateB()
{
// ...
}
}
Main problem with this ValueManipulator class is that i need to know T of IValue used in DoubleValue (in this case double). So it looks like this:
static void Main(string[] args)
{
ValueManipulator<double> doubleManipulator = new ValueManipulator<double>();
doubleManipulator.Manipulate(ProvideDoubles());
}
private static IEnumerable<DoubleValue> ProvideDoubles()
{
yield return new DoubleValue();
yield return new DoubleValue();
yield return new DoubleValue();
}
How do i make ValueManipulator so user does not need to know what type was used in value implementation?
Well, if your ValueManipulator<T> has no state, as appears to be your case according to your code snippets, then simply make the methods generic instead of the class, that way you can leverage type inference.
public class ValueManipulator
{
public void Manipulate<T>(IEnumerable<IValue<T>> pool)
{
foreach (int i in Enumerable.Range(0, pool.Count()))
{
IValue<T> firstValue = pool.ElementAt(i);
foreach (IValue<T> secondValue in pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
}
Now you can simply do:
ValueManipulator myManipulator = new ValueManipulator();
myManipulator.Manipulate(ProvideDoubles()); //type inference will figure out T is double
If this is a valid solution then consider making ValueManipulator a static class:
ValueManipulator.Manipulate(ProvideDoubles());
P.D. Please follow advice in commentaries and change ValueType to some other name thats less confusing.
UPDATE After your latest edit to your question, where you clearly state that ValueManipulator<T> does have state, the solution seems to be implementing a static factory class:
public static class ValueManipulator
{
public static ValueManipulator<T> Create<T>(IEnumerable<IValue<T>> pool)
=> new ValueManipulator<T>(pool);
}
public class ValueManipulator<T> { ... }
And again you let type inference do its job:
var doubleManipulator = ValueManipulator.Create(ProvideDoubles());
Can I use type parameter as implementing specific interface at Runtime without Reflection?
The following pseudocode is what I want to do.
void Run1<T> ()
{
// ...
if (typeof (IEnumerable).IsAssignableFrom (typeof (T)) {
Run2<T implementing IEnumerable> (); // <- use T as implementing IEnumerable
}
// ...
}
void Run2<T> () where T : IEnumerable
{
// ...
}
No, I don't believe there's a simple way you can do that.
If you're in control of all the code, you could have a public version of Run2 with the constraint, but a private implementation of Run2 without the constraint, which you call from Run1:
public void Run1<T>()
{
// ...
if (typeof(IEnumerable).IsAssignableFrom(typeof(T))
{
Run2Impl<T>();
}
// ...
}
public void Run2<T>() where T : IEnumerable
{
Run2Impl<T>();
}
private void Run2Impl<T>()
{
// Need to cast any values of T to IEnumerable here
}
If you were to drop the requirement of not using reflection, you could do this using a little detour.
public class Tester
{
private static readonly MethodInfo _run2Method = typeof(Tester).GetMethod("Run2");
public void Run1<T>()
{
if (typeof(IEnumerable).IsAssignableFrom(typeof(T)))
Run2AsIEnumerable<T>();
else
Console.WriteLine("Run1 for {0}", typeof(T));
}
public void Run2<T>() where T : IEnumerable
{
Console.WriteLine("Run2 for {0}", typeof(T));
}
private void Run2AsIEnumerable<T>()
{
Console.WriteLine("Detour to run2 for {0}", typeof(T));
var method = _run2Method.MakeGenericMethod(typeof(T));
method.Invoke(this, new object[0]);
}
}
Note that this could be made a bit more efficient by building and caching delegates for specific types on-demand.
The output of this:
new Tester().Run1<IEnumerable<int>>();
is:
Detour to run2 for System.Collections.Generic.IEnumerable`1[System.Int32]
Run2 for System.Collections.Generic.IEnumerable`1[System.Int32]
This is what I want to do in C# (within class Helper - without generic arguments),
List<AbstractClass<dynamic>> data;
public void Add<T>(AbstractClass<T> thing)
{
this.data.Add((AbstractClass<dynamic>) thing);
}
This helper class would take and work with AbstractClass<> objects and give back AbstractClass<> of specific generic type. AbstractClass<T> contains many functions which return T / take in T like public T Invoke().
For Helper class T cannot be known beforehand. The Add<T>(.. thing) function is not in a class of type T.
To be used like this in Helper class's functions,
foreach(var c in data.Where(x => ...))
{
// public T Invoke() { ... } function within AbstractClass<T>
var b = c.Invoke();
// logic
}
This also fails,
List<AbstractClass<object>> data;
public void Add<T>(AbstractClass<T> thing)
{
this.data.Add((AbstractClass<object>) thing);
}
Now I think I can have,
List<dynamic> data; // or List<object> data;
public void Add<T>(AbstractClass<T> thing)
{
this.data.Add(thing);
}
but I want the constraint that List named data has only elements of type like
ConcreteClass : AbstractClass<OtherClass>
So we would know that there is an public T Invoke() function but we do not know what it returns. This is helpful to avoid mistakes of say misspelling Invocke and only knowing at run-time.
I want to avoid casting to dynamic every time to invoke functions that give back generic type T
To do what you want to do you are going to need to use a Contravariant interface
public class Program
{
static void Main()
{
var m = new Helper();
m.Add(new ConcreteClass());
m.Process();
}
class Helper
{
List<IAbstractClass<OtherClassBase>> data = new List<IAbstractClass<OtherClassBase>>();
public void Add(IAbstractClass<OtherClassBase> thing)
{
this.data.Add(thing);
}
public void Process()
{
foreach(var c in data.Where(x => x.ShouldBeProcessed()))
{
var b = c.Invoke();
Console.WriteLine(b.Question);
var castData = b as OtherClass;
if (castData != null)
Console.WriteLine(castData.Answer);
}
}
}
public interface IAbstractClass<out T>
{
bool ShouldBeProcessed();
T Invoke();
}
abstract class AbstractClass<T> : IAbstractClass<T>
{
public bool ShouldBeProcessed()
{
return true;
}
public abstract T Invoke();
}
class ConcreteClass : AbstractClass<OtherClass>
{
public override OtherClass Invoke()
{
return new OtherClass();
}
}
class OtherClassBase
{
public string Question { get { return "What is the answer to life, universe, and everything?"; } }
}
class OtherClass : OtherClassBase
{
public int Answer { get { return 42; } }
}
}
You do not need to tell Add what kind of class you are passing it, all that matters is it derives from the type specified. You could do public void Add(IAbstractClass<object> thing) and every class would work, but Invoke() would only return objects inside the foreach loop.
You need to figure out what is the most derived class you want Invoke() to return and that is what you set as the type in the list.
Maybe this will work for you:
public class Program
{
static void Main()
{
var m1 = new Helper<OtherClass>();
m1.Add(new ConcreteClass());
var m2 = new Helper<int>();
m2.Add(new ConcreteClass2());
}
class Helper<T>
{
List<AbstractClass<T>> data = new List<AbstractClass<T>>();
public void Add<T1>(T1 thing) where T1 : AbstractClass<T>
{
this.data.Add(thing);
}
}
class AbstractClass<T> { }
class OtherClass { }
class ConcreteClass : AbstractClass<OtherClass> { }
class ConcreteClass2 : AbstractClass<int> { }
}
Is it possible to do something like the following:
public class ChildClass : BaseClass
{
public ChildClass(BaseClass o)
{
base = o;
}
}
Basically, I want a transparent way to wrap a base class inside of other functionality. One example I've thought of is a custom Settings Provider which transparently audits the settings passed through it.
public class SettingsAuditor : SettingsProvider
{
public SettingsAuditor(SettingsProvider o)
{
base = o;
}
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
{
// Log the property change to a file
base.SetPropertyValues(context, propvals);
}
}
Then I could do the following:
mySettingsProvider = new SettingsAuditor(mySettingsProvider);
And all changes would go through the overridden SetPropertyValues before passing to the original object.
I could use a private SettingsProvider member, but then I either cannot inherit from SettingsProvider, or have an entire SettingsProvider (base) not being used at all.
I'm using C# 4.0 and .Net 4.0.
You cannot do base = o;
What you're looking for is the Decorator Pattern), which is a way to compositionally add functionality at runtime (vs. inheritance).
Instead of trying to set the base, you just contain the inner member. As long as the wrapper implements the same interface or base class as the inner object, you can pass back the new wrapper. You can wrap as many decorators as you want.
Consider:
public interface ICar
{
void Drive();
}
public class Car : ICar
{
public void Drive()
{
Console.WriteLine("vroom");
}
}
public class BuckleUp : ICar
{
ICar car;
public BuckleUp(ICar car) { this.car = car; }
public void Drive()
{
Console.WriteLine("click!");
car.Drive();
}
}
public class CheckMirrors : ICar
{
ICar car;
public CheckMirrors(ICar car) { this.car = car; }
public void Drive()
{
Console.WriteLine("mirrors adjusted");
car.Drive();
}
}
Now consider you have a method that accepts an ICar and tells it to drive. You could give it a Car, and it would work, but you could also wrap that car in a BuckleUp and a CheckMirrors and you wouldn't have to change that method at all. You've modified functionality through composition using the Decorator Pattern.
No. This looks like it should be a Composition vs Inheritance issue. You need to evaluate whether you are a "is a" or a "has a."
A little help for your journey
This is not a complete implmentation and it could probably be done much cleaner with expression trees... but this was a quick swing at faking AOP using DynamicObject with .Net 4.0.
public class MyDynamicWrapper<T> : DynamicObject
{
public T Wrapped { get; private set; }
public Action<T> Pre { get; private set; }
public Action<T> Post { get; private set; }
public MyDynamicWrapper(T wrapped, Action<T> pre, Action<T> post)
{
this.Wrapped = wrapped;
this.Pre = pre;
this.Post = post;
}
public override bool TryGetMember(
GetMemberBinder binder,
out object result)
{
var type = typeof(T);
var method = type.GetMethod(binder.Name);
if (method != null)
{
Func<object> func = () =>
{
if (Pre != null)
Pre(Wrapped);
// support for input parameters could be added here
var ret = method.Invoke(Wrapped, null);
if (Post != null)
Post(Wrapped);
return ret;
};
result = func;
return true;
}
return base.TryGetMember(binder, out result);
}
}
public class MyDynamicWrapper
{
public static MyDynamicWrapper<T> Create<T>(
T toWrap,
Action<T> pre = null,
Action<T> post = null)
{
return new MyDynamicWrapper<T>(toWrap, pre, post);
}
}
public class MyObject
{
public void MyMethod()
{
Console.WriteLine("Do Something");
}
}
class Program
{
static void Main()
{
var myobject = new MyObject();
dynamic mydyn = MyDynamicWrapper.Create(
myobject,
p => Console.WriteLine("before"),
p => Console.WriteLine("after"));
// Note that you have no intellisence...
// but you could use the old implmentation before you
// changed to this wrapped version.
mydyn.MyMethod();
/* output below
before
Do Something
after
*/
}
}
No, but you could fake it:
public class SettingsAuditor
{
SettingsProvider #base;
public SettingsAuditor(SettingsProvider o)
{
#base = o;
}
public void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
{
// Log the property change to a file
#base.SetPropertyValues(context, propvals);
}
}
Note here, #base isn't the actual base, just a varaible named base
The Conditional Attribute in .NET allows you to disable the invocation of methods at compile time. I am looking for basically the same exact thing, but at run time. I feel like something like this should exist in AOP frameworks, but I don't know the name so I am having trouble figuring out if it is supported.
So as an example I'd like to do something like this
[RuntimeConditional("Bob")]
public static void M() {
Console.WriteLine("Executed Class1.M");
}
//.....
//Determines if a method should execute.
public bool RuntimeConditional(string[] conditions) {
bool shouldExecute = conditions[0] == "Bob";
return shouldExecute;
}
So where ever in code there is a call to the M method, it would first call RuntimeConditional and pass in Bob to determine if M should be executed.
You can actually use PostSharp to do what you want.
Here's a simple example you can use:
[Serializable]
public class RuntimeConditional : OnMethodInvocationAspect
{
private string[] _conditions;
public RuntimeConditional(params string[] conditions)
{
_conditions = conditions;
}
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
if (_conditions[0] == "Bob") // do whatever check you want here
{
eventArgs.Proceed();
}
}
}
Or, since you're just looking at "before" the method executes, you can use the OnMethodBoundaryAspect:
[Serializable]
public class RuntimeConditional : OnMethodBoundaryAspect
{
private string[] _conditions;
public RuntimeConditional(params string[] conditions)
{
_conditions = conditions;
}
public override void OnEntry(MethodExecutionEventArgs eventArgs)
{
if (_conditions[0] != "Bob")
{
eventArgs.FlowBehavior = FlowBehavior.Return; // return immediately without executing
}
}
}
If your methods have return values, you can deal with them too. eventArgs has a returnValue property that is settable.
I believe this would be a very simple way of doing what you described:
public static void M()
{
if (RuntimeConditional("Bob"))
{
Console.WriteLine("Executed Class1.M");
}
}
Thanks