I have the following function in c#:
bool Handle<TCommandHandler, TModel>(TModel model) where TCommandHandler : ICommandHandler<TModel> {
// ...
_container.Resolve<TCommandHandler>();
// ...
}
Since TModel is clear from a function parameter I want some way to not specify its type when calling a function. Ideally I want to call it like:
Handle<MyCommandHandler>(model);
Since this is probably impossible, I came up with the following:
HandleTemp<TModel> Handle<TModel>(TModel model) {
return new HandleTemp<TModel>(model);
}
public class HandleTemp<TModel> {
private TModel _model;
public HandleTemp(TModel model) { _model = model;}
public bool With<TCommandHandler>() where TCommandHandler : ICommandHandler<TModel> {
}
}
So I'm now calling it like:
Handle(model).With<MyCommandHandler>();
Are there other possibilities? Did I make something completely wrong with my solution?
No, your analysis and solution look about right. Indeed, generic type inference can work only on an all-or-nothing basis. If there are some generic parameters that can't be inferred, all must be explicitly stated. Personally I'd quite like a way to say "you worry about these parameters, I'll tell you this one", but... that doesn't exist.
The only other option is to add an artificial extra regular parameter to allow it to infer the generic parameter - a bit yucky.
One other option: challenge the assumption that generics are needed here. For example, could it just be a Type instance? Would:
bool Handle<TModel>(TModel model, Type type)...
...
Handle(model, typeof(MyCommandHandler));
work, for example? I can't answer this directly, as I don't know the particulars of your _container.Resolve<TCommandHandler>(); method, as to whether that could be adjusted to take a Type rather than a <T>.
All the C# compiler needs is a demonstration of the type in the arguments, so instead of attempting to place it in the generic arguments (at the usage site) make something that lets you provide an argument that helps the compiler identify that type. To make it less confusing, here is an example:
// Your classes/interfaces.
class Container
{
public static T Resolve<T>()
{
Console.WriteLine("Resolving {0}", typeof(T).FullName);
return default(T);
}
}
interface ICommandHandler<TModel>
{
void DoSomething();
}
// An implemented ICommandHandler.
public class WackyCommandHandler : ICommandHandler<string>
{
public void DoSomething() { }
}
// Used to help the C# compiler identify types.
public static class Identify
{
public static TypeIdentity<TType> TheType<TType>()
{
return null; // You don't actually need an instance.
}
}
public sealed class TypeIdentity<TType>
{
private TypeIdentity() { }
}
// Your method
static bool Handle<TCommandHandler, TModel>(TModel model, TypeIdentity<TCommandHandler> handler)
where TCommandHandler : ICommandHandler<TModel>
{
var item = Container.Resolve<TCommandHandler>();
return true;
}
// And the usage site:
var a = "hello";
Handle(a, Identify.TheType<WackyCommandHandler>());
Console.ReadLine();
Related
I have this piece of code that checks if an object is of type Sequence<T> which works as intended for objects of Type Task.
public class Sequence<T> {}
public class Task : Sequence<Task> {}
public class Program
{
public static void Main()
{
var task = new Task();
// These two are equivalent
Console.WriteLine(IsSequence(task));
Console.WriteLine(task is Sequence<Task>);
}
public static bool IsSequence<TEntity>(TEntity entity)
{
return entity is Sequence<TEntity>;
}
}
Now, however, I have a new requirement where these other types Tool and Assembly should also match, and I am pretty new to the pattern matching in C#, so not sure how to achieve it.
public class Sequence<T> {}
public abstract class Item : Sequence<Item> {}
public class Task : Sequence<Task> {}
public class Tool : Item {}
public class Assembly : Item {}
public class Program
{
public static void Main()
{
var ta = new Tool();
var tt = new Assembly();
var task = new Task();
Console.WriteLine(IsSequence(ta));
Console.WriteLine(IsSequence(tt));
Console.WriteLine(IsSequence(task));
// What I am posting here is an oversimplification of the real scenario
// This code for checking if something is a Sequence or not is
// handled by a core class with shared functionality that can't know or use the
// proper typed overload required.
//
// So doing this is not an option:
//
// Console.WriteLine(IsSequence<Item>(ta));
// This is how the output should be
Console.WriteLine(ta is Sequence<Item>);
Console.WriteLine(tt is Sequence<Item>);
Console.WriteLine(task is Sequence<Task>);
}
public static bool IsSequence<TEntity>(TEntity entity)
{
// How to rewrite (if possible) this pattern matching so that Task, Tool and Assembly match?
// So basically I want to know if either TEntity or some of the base types is Sequence<base>
return entity is Sequence<TEntity>;
}
}
I know that the way it is currently written, it won't match since Tool/Assembly are not Sequence<Tool>/Sequence<Assembly>, so I need a way to rewrite the pattern matching to check if it's Sequence<Item>.
Here is a C# Online Fiddle with this example.
The way you wrote your function won't work because Tool is not a Sequence<Tool>, it's a Sequence<Item>.
There are many, many ways to write your function if you choose to keep it, for whatever reason, but I'll give you two ways.
First, you can write it to receive an object argument then use is Sequence<T> inside to figure out if it's a sequence of something. The problem with this is that you need to provide the type argument every time, there's no inference here.
Second, you can write it like this:
public static bool IsSequence<TEntity>(Sequence<TEntity> entity) => true;
public static bool IsSequence(object obj) => false;
In this case there's no need to provide the type argument, just call it with your object and it will return the correct value. And since it relies on compile-time overload resolution, it's very efficient at runtime. Plus it should look familiar to any C++ programmer!
As a third option, extract an interface ISequence from your Sequence<T> class and then simply test with is ISequence with no type argument, since you don't seem to care about it in the test.
I heard the word Interface Duck Typing, but do not understand at all what is it? So I read a wiki about this and they said:
In computer programming with object-oriented programming languages, duck typing is a style of typing in which an object's methods and properties determine the valid semantics, rather than its inheritance from a particular class or implementation of an explicit interface. The name of the concept refers to the duck test.
But still could not understand what it. So I saw their program but they use dynamic keyword to call quack() & feather() function of all the classes.
I would request you all please explain in easy way what is Interface Duck Typing and how to implement in C# v2.0 because there is no dynamic keyword.
using System;
namespace DuckTyping
{
public class Duck
{
public void Quack()
{
Console.WriteLine("Quaaaaaack!");
}
public void Feathers()
{
Console.WriteLine("The duck has white and gray feathers.");
}
}
public class Person
{
public void Quack()
{
Console.WriteLine("The person imitates a duck.");
}
public void Feathers()
{
Console.WriteLine("The person takes a feather from the ground and shows it.");
}
}
internal class Program
{
private static void InTheForest(dynamic duck)
{
duck.Quack();
duck.Feathers();
}
private static void Game()
{
Duck donald = new Duck();
Person john = new Person();
InTheForest(donald);
InTheForest(john);
}
private static void Main()
{
Game();
}
}
}
C# has a nominal type system, so the compatibility of types is done based on their names. In your example you have two classes with a Quack method, however there is no way to write a method which can take instances of these two classes and invoke their Quack method.
In C# 2, the solution would be to introduce an interface and have both classes implement it:
public interface IQuack
{
void Quack();
}
public class Duck : IQuack { }
public class Human : IQuack { }
now you can create a method which take an IQuack instance and can call Human.Quack and Duck.Quack through it. In C#, methods are resolved 'early' at compile time, so you need to create a named type which supports the operations the method need so the compilation can succeed. Note there is still a runtime element to calling these methods, since the real implementation of IQuack.Quack needs to be resolved at runtime depending on the real type of the argument.
In a duck-typing system, no attempt is made to validate that a method exists before runtime. All that is required is that a given object supports the operation in that it has the right name and takes the required number of parameters (none in this case), hence the 'if it quacks like a duck' expression.
Duck typing in C# 2 can only be done using reflection, in this case you would accept an object argument and look for the required methods yourself:
public static void MakeQuack(object duck)
{
MethodInfo quackMethod = duck.GetType().GetMethod("Quack", Type.EmptyTypes, null);
if (quackMethod!=null)
{
quackMethod.Invoke(duck, new object[] { });
}
else
{
throw new ArgumentException("No Quack() method found on target");
}
}
C#4 makes this much simpler with dynamic:
public static void MakeQuack(dynamic duck)
{
duck.Quack();
}
It would say it is a way of coding where the you tell the compiler:
"Hey trust me I know what methods and properties this object supports. You don't need to check them for me whilst I code."
Once you run your app the compiler will go:
"Ok lets see if I could trust you. Let me do some runtime binding."
If you then made a mistake, such as using an unsupported method, the compiler will shout: "Hey man, this is not supported! Check my RuntimeBinderException!"
Duck typing allows an object to be passed in to a method that expects
a certain type even if it doesn’t inherit from that type. All it has
to do is support the methods and properties of the expected type in
use by the method. I emphasize that last phrase for a reason. Suppose
we have a method that takes in a duck instance, and another method
that takes in a rabbit instance. In a dynamically typed language that
supports duck typing, I can pass in my object to the first method as
long as my object supports the methods and properties of duck in use
by that method. Likewise, I can pass my object into the second method
as long as it supports the methods and properties of rabbit called by
the second method. Is my object a duck or is it a rabbit? Like the
above image, it’s neither and it’s both. In many (if not most) dynamic
languages, my object does not have to support all methods and
properties of duck to be passed into a method that expects a duck.
Same goes for a method that expects a rabbit.It only needs to support
the methods and properties of the expected type that are actually
called by the method.
Please refer this to get an idea about Duck Typing
http://haacked.com/archive/2007/08/19/why-duck-typing-matters-to-c-developers.aspx/
About Duck Typing:
We don't need to know what the object is, but we just want to let the
object do something if it can do.
Example:
Example, if here are the things that we want the following objects do.
PleaseWalk(new Dog());
PleaseRun(new Duck());
PleaseWalk(new Cup());
PleaseFly(new Man());
PleaseFly(new Bird());
And, here is the result after we request the above objects do the things.
So, we don't need to check what the object is, but we can let it do something enough. Here is the code that I have written in C#.
private void PleaseWalk(object obj)
{
string Method = "Walk";
MethodInfo walkMethod = obj.GetType().GetMethod(Method, Type.EmptyTypes, null);
if (walkMethod != null)
{
walkMethod.Invoke(obj, new object[] { });
}
else
{
Console.WriteLine(string.Format("I can not {0} because {1}", Method, WhoAreYou(obj)));
}
}
private string WhoAreYou(object unknown)
{
MethodInfo whoAreYou = unknown.GetType().GetMethod("WhoAreYou", Type.EmptyTypes, null);
return whoAreYou.Invoke(unknown, new object[] { }).ToString();
}
You can use Events and exploit C# best suitable overload functions.
Hopefully, it will be useful :)
To get something Like a duck typing (.Net 4.+):
using System.Collections;
using System.Collections.Generic;
public interface IAny
{
void InvokeGetterEvent();
}
public class AnyValueTypeDuck<T, V> : IAny
where V : AnyValueTypeDuck<T, V>
{
public static event System.Action<V> GetterEvent;
public T Data;
public void InvokeGetterEvent()
{
GetterEvent.Invoke((V)this);
}
}
// Then create some concrete classes:
// Example :
public class LifeConcreteProperty : AnyValueTypeDuck<int, LifeConcreteProperty>
{
}
public class ManaConcreteProperty : AnyValueTypeDuck<float, ManaConcreteProperty>
{
}
// Now to finally use it :
public class UserClass
{
List<IAny> allDuckTypes = new List<IAny>();
public void GetDucketTypeClass(IAny anyDuckObject)
{
LifeConcreteProperty.GetterEvent += GetDucketType;
ManaConcreteProperty.GetterEvent += GetDucketType;
anyDuckObject.InvokeGetterEvent();
// it will propagate to event and will invoke
// best suitable overload method (GetDucketType)
LifeConcreteProperty.GetterEvent -= GetDucketType;
ManaConcreteProperty.GetterEvent -= GetDucketType;
}
public void GetDucketType(LifeConcreteProperty originalClass)
{
// Your efforts go here
int value = originalClass.Data;
}
public void GetDucketType(ManaConcreteProperty originalClass)
{
// Your efforts go here
float value = originalClass.Data;
}
}
I don't even know how to ask this question so I'll just give the code example.
Here is the domain:
public interface ISubscriptionProvider<T>
{
void Subscribe(Action<T> callback);
}
public class Notification {}
public class CurrentUserNotifications : ISubscriptionProvider<Notification>
{
public void Subscribe(Action<Notification> callback) { }
}
Here is the method I want to make magical:
public void Subscribe<P, T>(Action<T> callback) where P : ISubscriptionProvider<T>
{
// body left out -- code uses P
}
This works, and here is how you call it:
Subscribe<CurrentUserNotifications, Notification>((n) => Console.WriteLine(n));
So the question is: Is there any way to make it callable like this:
Subscribe<CurrentUserNotifications>((n) => Console.WriteLine(n));
Basically, can it infer that the action type should be just from the ISubscriptionProvider<T>.
This subscribe method lives on a static class (its a static method, I left that part out). The idea is that it will take care of constructing the ISubscriptionProvider<T> and keeping it a singleton (probably with structuremap). So in use:
Messages.Subscribe<CurrentUserNotifications>((n) => Console.WriteLine(n));
Thanks!
Update:
This is kinda off topic, but if any scala people read this ...
... is be an example of a higher kinded type? Something like:
public void Subscribe<P<T>>(Action<T> callback) { }
Where P<_> is the higher kinded type?
Why can't you just use
public void Subscribe<T>(Action<T> callback)
{
}
The type P Parameter is irrelevant in your scenario as it is never used.
i have generic method. i want generic method to limit one type. problem is derived type not to be allowed - i do not want this. example codes:
public static T Generate<T>(T input)
where T : Operation // ALLOWS BinaryOperation - NOT WANT THIS
{
//...
}
how to do what I request?
problem is derived type not to be allowed
There is no way to enforce this constraint, without checking it at runtime. Doing so would be a violation of the Liskov Substitution Principle, which states that any type should allow you to pass in a derived type without restriction.
If you must enforce this, it will only work with a runtime check, like:
public static T Generate<T>(T input)
where T : Operation // ALLOWS BinaryOperation - NOT WANT THIS
{
// Checks to see if it is "Operation" (and not derived type)
if (input.GetType() != typeof(Operation))
{
// Handle bad case here...
}
// Alternatively, if you only want to not allow "BinaryOperation", you can do:
if (input is BinaryOperation)
{
// Handle "bad" case of a BinaryOperation passed in here...
}
}
Note that, in this case, there's really no reason to make it generic, as the same code would work as:
public static Operation Generate(Operation input)
{ // ...
It's not possible to force a method to accept only one specific type like Operation if the type is not a struct or a sealed class.
Let's me show this in a example why this won't work anyway:
public void Generate<T>(Operation op)
// We assume that there is the keyword "force" to allow only Operation classes
// to be passed
where T : force Operation
{ ... }
public void DoSomething()
{
Generate(new BitOperation()); // Will not build
// "GetOperation" retrieves a Operation class, but at this point you dont
// know if its "Operation" or not
Operation op = GetOperation();
Generate(op); // Will pass
}
public Operation GetOperation() { return new BitOperation(); }
As you can see it will be easy to pass a BitOperation even when there is a restriction.
Solution
There is only one solution beside the others mentioned above ( struct, sealed ): Runtime Check.
You can write yourself a little helper method for this.
public class RuntimeHelper
{
public static void CheckType<T>(this Object #this)
{
if (typeof(T) != #this.GetType())
throw new ....;
}
}
Usage
public void Generate(Operation op)
{
op.CheckType<Operation>(); // Throws an error when BitOperation is passed
}
Little Note
If you want to speed up the helper you could use a generic class RuntimeHelper<T> with a static readonly type variable which has the type of T.
When you're doing this you cannot longer use extension methods so the call would look like this:
RuntimeHelper<Operation>.CheckType(op);
imagine you have the following interfaces:
public interface IInterfaceA : IInterfaceX
{
//
// declarations
//
}
public interface IInterfaceB : IInterfaceX
{
//
// declarations
//
}
public interface IInterfaceC : IInterfaceX
{
//
// declarations
//
}
Now I want to replace the following three methods which perform almost the same with a single function:
class SomeClass
{
IInterfaceA myVarA;
IInterfaceB myVarB;
IInterfaceC myVarC;
void SomeMethodA(IInterfaceX someVarX)
{
myVarA = (IInterfaceA)someVarX;
}
void SomeMethodB(IInterfaceX someVarX)
{
myVarB = (IInterfaceB)someVarX;
}
void SomeMethodC(IInterfaceX someVarX)
{
myVarC = (IInterfaceC)someVarX;
}
}
I thought about something like:
void SomeMethod(IInterfaceX targetVar, IInterfaceX someVarX)
{
//
// here's my problem
//
targetVar = (CastIDontKnowHowToPerform)someVarX;
}
which is used sth. like
SomeMethod(myVarA, someVarX);
SomeMethod(myVarB, someVarX);
SomeMethod(myVarC, someVarX);
So my questions are:
Is it possible what I want to get?
How to perform this cast I don't know how to perform?
Perhaps a design pattern is more appropriate
I'm just looking for the best way to refactor those three functions by replacing them by a single one.
Things I've tried so far:
I used things like object.GetType() and object.GetType().GetInterfaces() which works well to get the type of an object or its interface(s) but none to set the type of an object to its interface.
Hope you can help me...
Regards,
Inno
[EDIT]
Ah, damn it... after clicking "Ask your question" and having a short look at it this seems to a be typical case for a generic function (or a template in C++-term).
[/EDIT]
void SomeMethod<T>(out T targetVar, IInterfaceX someVarX) where T: IInterfaceX
{
targetVar = (T) someVarX;
}
One possibility is the "is" operator:
void SomeMethod(IInterfaceX someVarX)
{
if (someVarX is IInterfaceA)
SomeMethodA((IInterfaceA)someVarX);
else if (...
}
A better method would be to put the operation into the IInterfaceX to avoid casting altogether:
void SomeMethod(IInterfaceX someVarX)
{
someVarX.SomeMethod();
}