I'm trying to somehow determine based on my interface what type came in and then do some validation on that type. Validation differes based on type that comes in.
public static bool RequestIsValid(IPaymentRequest preAuthorizeRequest)
{
switch (preAuthorizeRequest)
{
case
}
}
but either I can't do that with an interface or I'm not doing something that will make this work.
If I can't do that on an interface which looks like the probably because I think switch needs a concrete type, then how would I do this? Just regular if statements that check typeof?
Is that the only way?
Just for completeness:
You could also overload the method for the different implementations of IPaymentRequests and remove the one that takes the interface as parameter if you don't need a "default" handling. This is also safer because adding new implementations that apparently MIGHT require special handling do not default to something, but require another method with matching signature
public static bool RequestIsValid(PaymentRequestImplementation1 preAuthorizeRequest)
{
}
public static bool RequestIsValid(PaymentRequestImplementation2 preAuthorizeRequest)
{
}
...
If you really want to keep the method taking an IRequest you can also use reflection to call the more specific methods in case your caller casts your argument in an IRequest :
public static bool RequestIsValid(IRequest preAuthorizeRequest)
{
var member = typeof (YourType).GetMethod(
"RequestIsValid",
BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public,
null,
new [] {preAuthorizeRequest.GetType()},
null);
if (member.GetParameters()[0].ParameterType != typeof (IRequest))
{
member.Invoke(null, new[] {Convert.ChangeType(preAuthorizeRequest, preAuthorizeRequest.GetType())});
}
// default
}
You'd have to use GetType method and typeof(), but unfortunately you cannot use switch/case to make a decision:
A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type.
You can use if/else statements or prepare Dictionary<Type, Func<IPaymentRequest, bool>> and use it to perform your validation logic.
private static Dictionary<Type, Func<IInterface, bool>> _validationFunctions
= new Dictionary<Type, Func<IInterface, bool>>() {
{ typeof(ClassA), (input) => false },
{ typeof(ClassB), (input) => true }
};
public static bool RequestIsValid(IInterface preAuthorizeRequest)
{
return _validationFunctions[preAuthorizeRequest.GetType()](preAuthorizeRequest);
}
You can use is or as like this:
public static bool RequestIsValid(IPaymentRequest preAuthorizeRequest)
{
if (preAuthorizeRequest is PaymentRequestClassA)
{
var classA = (PaymentRequestClassA)preAuthorizeRequest;
// handle PaymentRequestTypeA
}
else if (preAuthorizeRequest is PaymentRequestClassB)
{
var classA = (PaymentRequestClassB)preAuthorizeRequest;
// handle PaymentRequestTypeB
}
}
Or
public static bool RequestIsValid(IPaymentRequest preAuthorizeRequest)
{
var classA = preAuthorizeRequest as PaymentRequestClassA;
var classB = preAuthorizeRequest as PaymentRequestClassB;
if (classA != null)
{
// handle PaymentRequestTypeA
}
else if (classB != null)
{
// handle PaymentRequestTypeB
}
}
Related
I have a generic function which is like below
private List<T> GetAll<T>()
{
var listOfTModels = // gets the list of T from the database.
return listOfTModels;
}
I need to pass the model ( T ) dynamically to this function based on a string which will be decided at runtime.
public void SomeFunction(string modelName)
{
// Call the above Get method with modelName parameter as the 'T'
var listOfModels = GetAll<something>(); //not sure what type this something should be "Type" or "string"
// Further Logic on listOfModels
}
How could this be done?
You will need to use reflection to get the method like so:
typeof(ClassWithGetAll).GetMethod("GetAll",
BindingFlags.Instance | BindingFlags.NonPublic);
This will return a method info which you will then use to create a generic method via MakeGenericMethod.
The only way to get a type from a string name AFAIK is with Type.GetType but you will need a AssemblyQualifiedName for that, so passing in a short/simplified name like string or int or anything like that will more than likely return null.
If you figure out how to either get the qualified name or how to search for the type, the last thing would be to invoke the MethodInfo returned from the MakeGenericMethod call, here is a example of how the code could look:
public void SomeFunction(string modelName)
{
// No idea what the class/struct in which the method "GetAll"
// is called, hence use this name
var instance = new ClassWithGetAll();
//Retrieves the info of "GetAll<T>"
MethodInfo method = typeof(ClassWithGetAll).GetMethod("GetAll",
BindingFlags.Instance | BindingFlags.NonPublic);
//Commented out as you will need to figure out how to get the
// assembly qualified name of the input model name, unless
// it is qualified.
//modelName = GetAssemblyQualifiedName(modelName);
Type modelType = Type.GetType(modelName);
//Creates a generic method: "GetAll<T>" => "GetAll<modelType>"
method = method.MakeGenericMethod(modelType);
//Invokes the newly created generic method in the specified
// instance with null parameters, which returns List<modelType>
object list = method.Invoke(instance, null);
}
I think inheritance would be the right way to solve your problem.
public class TBase
{
public int Prop { get; set; }
}
public class TChildOne : TBase
{
}
public class TChildTwo : TBase
{
}
public class GClass
{
private List<T> GetAll<T>() where T : TBase
{
var listOfTModels = // gets the list of T from the database.
return listOfTModels;
}
public void Main(string strType)
{
switch (strType)
{
case "TChildOne":
{
var child = GetAll<TChildOne>();
break;
}
case "TChildTwo":
{
var child = GetAll<TChildTwo>();
break;
}
default:
throw new Exception("type not found");
}
}
}
I want to implement this method from MOQ. (Little out of my depth here)
ISetup<T> Setup(Expression<Action<T>> expression);
public class Foo {
public string Bar { get; set; }
public int Baz { get; set; }
}
public class MyCoolClass
{
public ? Evaluate<Expression<Action>>(expression);
//I want to be able to access and test the value of Foo.Bar (see below)
}
public class ClientOfMyClass
{
public void UseTheMethod()
{
MyCoolClass myCool = new MyCoolClass();
bool result = myCool.Evaluate<Foo>(f => f.Bar);
}
}
Basically, I am trying to write a method that will allow the caller to specify a property on an object with an expression, and allow me to test the value of that property and do something with it.
You want to use an Expression<Func<>> parameter, and check that it contains a Body, and a Member of type PropertyInfo, and use GetValue() passing your object in.
public static void Evaluate<TObj,TProp>(
this TObj obj,
Expression<Func<TObj, TProp>> expr)
{
var prop = (expr.Body as MemberExpression)?.Member as PropertyInfo;
var val = prop?.GetValue(obj);
if (val != null) {
//Do something
}
}
Note that the above code requires the passed in lambda to point to a Property. If you want to handle Fields as well as Methods, they will come in as different types of Expressions, and you'll want to handle handle them slightly differently. For more context and usage, here's a Fiddle.
Edit: Updated to work with other property types.
Here's a method delegate that I have :
delegate void ExceptionHandelr<T>(T exception,out bool handeled) where T:Exception;
I would like to have a registry of these kind of method so I could call them based on the type of their methods something like this :
var method=ErrorHandlers[typeof(NullReferenceException)];
method(exception as NullReferenceException,out handled);
How I can implement this registry? I can't have a Dictionary<T,Method<T>> can I ?
I would do something like this:
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Test
{
class MainApp
{
public class ExceptionRegistry
{
Dictionary<Type, object> registry = new Dictionary<Type, object>();
private Func<T, bool> Get<T>() where T : Exception
{
return registry[typeof(T)] as Func<T, bool>;
}
private bool Invoke<T>(T exception) where T : Exception
{
return Get<T>().Invoke(exception);
}
public bool Invoke(Exception exception)
{
MethodInfo method = this.GetType().GetMethod("Invoke", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo generic = method.MakeGenericMethod(exception.GetType());
var result = generic.Invoke(this, new object[] { exception });
return (bool)result;
}
public void Add<T>(Func<T, bool> handler) where T : Exception
{
registry.Add(typeof(T), handler);
}
}
static void Main()
{
ExceptionRegistry registry = new ExceptionRegistry();
registry.Add<ArgumentException>((ArgumentException exception) =>
{
// some logic
return true;
});
Exception ex = new ArgumentException();
bool result = registry.Invoke(ex);
}
}
}
I would create a Dictionary<Type, Delegate> and than executed the delegate using DynamicInvoke method.
http://msdn.microsoft.com/en-us/library/system.delegate.dynamicinvoke.aspx
Bit of a late answer, but I fancied giving it anyway :)
You could use a static, generic helper class to store and retrieve the handlers in a strongly-typed, type-safe fashion:
public static class ExceptionHandlers<TEx>
where TEx : Exception
{
public static ExceptionHandler<TEx> Handle
{
get;
set;
}
}
You'd assign handlers in one place:
public static void MyExceptionHandler(MyException exception, out bool handled)
{
// Handling logic...
}
...
ExceptionHandlers<MyException>.Handle = MyExceptionHandler;
...and use them wherever you needed to:
try
{
// Something...
}
catch(MyException myEx)
{
bool handled;
ExceptionHandlers<MyException>.Handle(myEx, out handled);
}
A single instance of each unique ExceptionHandler<TEx> is created at runtime as different TEx types are used, and as desired, you've got handlers with no casting :)
It would also be pretty easy to extend this solution to use collections of handlers if required.
One could have a dictionary such as you describe, but a somewhat better pattern would be to follow the lead of Comparer<T>. Implement a generic type with a static field of a suitable delegate type, along with means of querying the field, or setting it if it hasn't been set yet. If desired, you could even have the default value of the field be a routine which would examine the type to see if it implements some interface, and make the delegate point to an interface method if appropriate.
Is it possible to create a generically typed Action at run time based on some specified types? In this particular scenario, the body of the Action will ultimately ignore the argument types, as the typed Action<> will just be a wrapper around a no-argument Action, e.g.
Action original = () => { };
...
Action<TType> wrapper = (arg) => {
original();
}
Or, even:
Action<TTypeA, TTypeB> wrapper = (arg) => {
original();
}
As you can see, the body of the typed Action<> ignores the arguments, and their type, it's just acting as a wrapper.
If you're curious as to why I want create this wrapper in the first place, the 'basic' version is that I am ultimately converting the Action to a Delegate for doing a Delegate.Combine(), which requires identical types. All I am trying to accomplish with the Delegate.Combine() is a basic notification that the delegate was fired.
At this point I will probably re-work my design to avoid these types of shenanigans, but I am still very curious how this might be accomplished.
The closest I could get was the following:
private static TType GetTypedDelegate<TType>(Action onComplete)
where TType : class
{
MethodInfo info = typeof(TType).GetMethod("Invoke");
ParameterInfo[] parameters = info.GetParameters();
object result;
if (parameters.Length == 0)
result = onComplete;
else if (parameters.Length == 1)
result = GetTypedDelegate<TType>(onComplete, parameters[0].ParameterType);
// etc
TType onCompleteCasted = Delegate.CreateDelegate(typeof(TType), result, "Invoke") as TType;
return onCompleteCasted;
}
private static Delegate GetTypedDelegate<TType>(Action onComplete, Type type)
{
// This line isn't useful for me right now, since I can't just create a new
// instance of the action with a parameterless constructor ... but I thought I'd throw it in here in case it was of use
Type actionType = typeof(Action<>).MakeGenericType(new[] { type });
// Do some magic here with the type information
// The following of course does not work,but you get the idea of what I am aiming for
Action<type> wrapper = (arg1) =>
{
onComplete();
};
return wrapper as Delegate;
}
I think that the easiest option is to write a generic method and then invoke it dynamically (using Reflection or possibly even using C# 4 dynamic):
class Helper {
public static Action<TType> Wrap1<TType>(Action arg) {
return (arg) => { original(); }
}
}
Invoking the method using Reflection and using typ1 as the generic type argument could look like this:
var meth = typeof(Helper).GetMethod("Wrap1");
var gmeth = meth.MakeGenericMethod(new[] { typ1 });
var genericAction = gmeth.Invoke(null, new object[] { action });
If you don't want to use reflection you can setup some classes like this.
public class ActionWrapper<TTypeA>
{
protected readonly Action _original;
public ActionWrapper(Action original)
{
_original = original;
}
public Action<TTypeA> Wrapped { get { return WrappedAction; } }
private void WrappedAction(TTypeA a)
{
_original();
}
}
public class ActionWrapper<TTypeA,TTypeB>:ActionWrapper<TTypeA>
{
public ActionWrapper(Action original) : base(original)
{
}
public new Action<TTypeA, TTypeB> Wrapped { get { return WrappedAction; } }
private void WrappedAction(TTypeA a,TTypeB b)
{
_original();
}
}
Consider the following (heavily simplified) code:
public T Function<T>() {
if (typeof(T) == typeof(string)) {
return (T) (object) "hello";
}
...
}
It's kind of absurd to first cast to object, then to T. But the compiler has no way of knowing that the previous test assured T is of type string.
What is the most elegant, idiomatic way of achieving this behavior in C# (which includes getting rid of the stupid typeof(T) == typeof(string), since T is string can't be used)?
Addendum: There is no return type variance in .net, so you can't make a function overload to type string (which, by the way, is just an example, but one reason why association end redefinition in polymorphism, e.g. UML, can't be done in c#). Obviously, the following would be great, but it doesn't work:
public T Function<T>() {
...
}
public string Function<string>() {
return "hello";
}
Concrete Example 1: Because there's been several attacks to the fact that a generic function that tests for specific types isn't generic, I'll try to provide a more complete example. Consider the Type-Square design pattern. Here follows a snippet:
public class Entity {
Dictionary<PropertyType, object> properties;
public T GetTypedProperty<T>(PropertyType p) {
var val = properties[p];
if (typeof(T) == typeof(string) {
(T) (object) p.ToString(this); // magic going here
}
return (T) TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(val);
}
}
Concrete Example 2: Consider the Interpreter design pattern:
public class Expression {
public virtual object Execute() { }
}
public class StringExpression: Expression {
public override string Execute() { } // Error! Type variance not allowed...
}
Now let's use generics in Execute to allow the caller to force a return type:
public class Expression {
public virtual T Execute<T>() {
if(typeof(T) == typeof(string)) { // what happens when I want a string result from a non-string expression?
return (T) (object) do_some_magic_and_return_a_string();
} else if(typeof(T) == typeof(bool)) { // what about bools? any number != 0 should be True. Non-empty lists should be True. Not null should be True
return (T) (object) do_some_magic_and_return_a_bool();
}
}
}
public class StringExpression: Expressiong {
public override T Execute<T>() where T: string {
return (T) string_result;
}
}
If you're making these types of checks in a generic method, I'd rethink your design. The method is obviously not truly generic - if it were, you wouldn't need specific type checking...
Situations like this typically can be handled more cleanly by a redesign. One alternative is often to provide an overload of the appropriate type. Other design alternatives which avoid the type-specific behavior exist, as well, such as Richard Berg's suggestion of passing in a delegate.
using System;
using System.Collections.Generic;
using System.Linq;
namespace SimpleExamples
{
/// <summary>
/// Compiled but not run. Copypasta at your own risk!
/// </summary>
public class Tester
{
public static void Main(string[] args)
{
// Contrived example #1: pushing type-specific functionality up the call stack
var strResult = Example1.Calculate<string>("hello", s => "Could not calculate " + s);
var intResult = Example1.Calculate<int>(1234, i => -1);
// Contrived example #2: overriding default behavior with an alternative that's optimized for a certain type
var list1 = new List<int> { 1, 2, 3 };
var list2 = new int[] { 4, 5, 6 };
Example2<int>.DoSomething(list1, list2);
var list1H = new HashSet<int> { 1, 2, 3 };
Example2<int>.DoSomething<HashSet<int>>(list1H, list2, (l1, l2) => l1.UnionWith(l2));
}
}
public static class Example1
{
public static TParam Calculate<TParam>(TParam param, Func<TParam, TParam> errorMessage)
{
bool success;
var result = CalculateInternal<TParam>(param, out success);
if (success)
return result;
else
return errorMessage(param);
}
private static TParam CalculateInternal<TParam>(TParam param, out bool success)
{
throw new NotImplementedException();
}
}
public static class Example2<T>
{
public static void DoSomething(ICollection<T> list1, IEnumerable<T> list2)
{
Action<ICollection<T>, IEnumerable<T>> genericUnion = (l1, l2) =>
{
foreach (var item in l2)
{
l1.Add(item);
}
l1 = l1.Distinct().ToList();
};
DoSomething<ICollection<T>>(list1, list2, genericUnion);
}
public static void DoSomething<TList>(TList list1, IEnumerable<T> list2, Action<TList, IEnumerable<T>> specializedUnion)
where TList : ICollection<T>
{
/* stuff happens */
specializedUnion(list1, list2);
/* other stuff happens */
}
}
}
/// I confess I don't completely understand what your code was trying to do, here's my best shot
namespace TypeSquarePattern
{
public enum Property
{
A,
B,
C,
}
public class Entity
{
Dictionary<Property, object> properties;
Dictionary<Property, Type> propertyTypes;
public T GetTypedProperty<T>(Property p)
{
var val = properties[p];
var type = propertyTypes[p];
// invoke the cast operator [including user defined casts] between whatever val was stored as, and the appropriate type as
// determined by the domain model [represented here as a simple Dictionary; actual implementation is probably more complex]
val = Convert.ChangeType(val, type);
// now create a strongly-typed object that matches what the caller wanted
return (T)val;
}
}
}
/// Solving this one is a straightforward application of the deferred-execution patterns I demonstrated earlier
namespace InterpreterPattern
{
public class Expression<TResult>
{
protected TResult _value;
private Func<TResult, bool> _tester;
private TResult _fallback;
protected Expression(Func<TResult, bool> tester, TResult fallback)
{
_tester = tester;
_fallback = fallback;
}
public TResult Execute()
{
if (_tester(_value))
return _value;
else
return _fallback;
}
}
public class StringExpression : Expression<string>
{
public StringExpression()
: base(s => string.IsNullOrEmpty(s), "something else")
{ }
}
public class Tuple3Expression<T> : Expression<IList<T>>
{
public Tuple3Expression()
: base(t => t != null && t.Count == 3, new List<T> { default(T), default(T), default(T) })
{ }
}
}
Can you use as here?
T s = "hello" as T;
if(s != null)
return s;
I can't think of an "elegant" way to do this. As you say, the compiler can't know that the conditional has ensured that the type of T is string. As a result, it has to assume that, since there's no generalized way to convert from string to T, it's an error. object to T might succeed, so the compiler allows it.
I'm not sure I'd want an elegant way to express this. Although I can see where it'd be necessary to do explicit type checks like this in some situations, I think I'd want it to be cumbersome because it really is a bit of a hack. And I'd want it to stick out: "Hey! I'm doing something weird here!"
Ok, I took a run at it from several different angles and came up short. I would have to conclude that if your current implementation gets the job done you should take the win and move on. Short of some arcane emissions what you got is what you get.
But the compiler has no way of knowing
that the previous test assured T is of
type string.
Umm.... If I am not mistaken, generics is just code gen. The compiler generates a matching method for each distinct type found in the calling methods. So the compiler does know the type argument for the overload being called. Again; If I am not mistaken.
But overall, i think you are misusing the generic in this case, from what I can see, and as others have stated, there are more appropriate solutions..... which are unnamable unless you post code that completely specifies your requirements.
just my 2 pesos...