Overloading methods in C# .NET - c#

A variable of the type Int32 won't be threated as Int32 if we cast it to "Object" before passing to the overloaded methods below:
public static void MethodName(int a)
{
Console.WriteLine("int");
}
public static void MethodName(object a)
{
Console.ReadLine();
}
To handle it as an Int32 even if it is cast to "Object" can be achieved through reflection:
public static void MethodName(object a)
{
if(a.GetType() == typeof(int))
{
Console.WriteLine("int");
}
else
{
Console.ReadLine();
}
}
Is there another way to do that? Maybe using Generics?

Runtime overload resolution will not be available until C# 4.0, which has dynamic:
public class Bar
{
public void Foo(int x)
{
Console.WriteLine("int");
}
public void Foo(string x)
{
Console.WriteLine("string");
}
public void Foo(object x)
{
Console.WriteLine("dunno");
}
public void DynamicFoo(object x)
{
((dynamic)this).Foo(x);
}
}
object a = 5;
object b = "hi";
object c = 2.1;
Bar bar = new Bar();
bar.DynamicFoo(a);
bar.DynamicFoo(b);
bar.DynamicFoo(c);
Casting this to dynamic enables the dynamic overloading support, so the DynamicFoo wrapper method is able to call the best fitting Foo overload based on the runtime type of the argument.

public static void MethodName(object a)
{
if(a is int)
{
Console.WriteLine("int");
}
else
{
Console.WriteLine("object");
}
}

No, the specific overload of a method that is called is determined at compile-time, not at runtime, unless you're using reflection, thus if you've cast your int to an object, the object overload will be called. I don't believe there's any other way to do this, and generics won't do it for you either.

would this not work?
void MethodName<T>(object a){
T item = a as T;
// treat in the manner you require
}
MethodName<object>(1);
MethodName<Int32>(1);

Perhaps:
public static void MethodName(Type t)
{
Console.WriteLine(t.Name);
}
Then call it:
int a = 0;
string b = "";
object c = new object();
MethodName(a.GetType());
MethodName(b.GetType());
MethodName(c.GetType());
Or:
public static void MethodName<T>(T a)
{
Console.WriteLine(a.GetType().Name);
}
And finally:
public static void MethodName<T>()
{
Console.WriteLine(typeof(T).Name);
}
Update:
It comes down to the fact that the language must somehow be able to determine what type you will be dealing at compile time.

You're pretty much stuck with if/else constructs if you're looking to switch on types. The switch statement itself won't work due to polymorphism. If you're using non-primitive objects, than you can usually accomplish this sort of behavior either with polymorphism or interfaces, such that:
public static void MethodName(MyBaseObject obj)
{
Console.WriteLine(obj.MyVirtualFunctionCall());
}

dynamic overloading was an issue until .NET 3.5, but with .NET 4 its very feasible with few lines of code.
public void publish(dynamic queue)
{
publish(queue);
Console.WriteLine("dynamic queue publishing");
}
public void publish(ValidationQueue queue)
{
Console.WriteLine("Validation queue publishing");
}
how to call
foreach (var queue in _vodaQueueDAO.FetchAllReadyQueuesWithHighestPriority())
{
PublishingService.publish(queue);
}

I wrote an implementation for .NET 3.5 where you e.g. can do something like:
object a = 5;
OverloadResolver.Invoke(MethodName, a);
and it would use the int overload.
Works with compiled and cached Lambda expressions so the performance should be ok.
If anybody needs it, mail me, herzmeisterderwelten, who resides at gmail.com

Related

C#: Call overloaded method in external assembly from generic

I have a project that references a 3rd party c# assembly containing several overloaded instance methods. I want to invoke one of these methods via a generic in my code, calling the instance method whose parameter type matches the type of the generic:
void GetVal<T>(ref T val)
{
VendorLib v = new VendorLib();
v.GetVal(ref val);
}
// error CS1503: Argument 1: cannot convert from 'ref T' to 'ref bool'
The closest I have come is through the use of a dynamic variable, but this results in a runtime exception as the parameter d resolves to bool even though the type of the generic is ulong, thereby binding the incorrect method:
class MyClass
{
void Caller()
{
ulong val = 0;
this.GetValue<ulong>(ref val);
}
void GetValue<T>(ref T val)
{
dynamic d = val;
GetValDynamic(ref d);
}
void GetValDynamic(ref dynamic val)
{
VendorLib v = new VendorLib();
v.GetVal(ref val);
}
}
Exception:
Result Message: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : The best overloaded method match for 'VendorLib.GetVal(ref bool)' has some invalid arguments
The vendor library contains several GetVal overloads, of which GetVal(ref bool) is one and GetVal(ref ulong) another.
Why is the correct method not being bound?
Thanks!
If you don't want to check typeof(T) and call the respective method manually then reflection can work. Something like this...
public class MyVendorLibWrapper
{
private readonly VendorLib vendorLib;
public MyVendorLibWrapper()
{
this.vendorLib = new VendorLib();
}
public T GetValue<T>()
{
MethodInfo method = typeof(VendorLib)
.GetMethod("GetVal", new Type[] { typeof(T).MakeByRefType() });
object[] arguments = new object[] { default(T) };
method.Invoke(this.vendorLib, arguments);
return (T)arguments[0];
}
}
And called something like this...
MyVendorLibWrapper wrapper = new MyVendorLibWrapper();
int x = wrapper.GetValue<int>();
val is a dynamic, not a bool or a ulong. It is the wrong type. By using dynamic you are just cheating yourself out of the compile-time checking and just getting an error at runtime instead.
Looking at the way this code works the only purpose of generics and dynamic is to find a way to pass either a bool or a ulong to GetVal(...). From your code it looks like the only method that might need to be public is Caller(), in which case you can hide all this behind a common interface.
class MyClassULong : IMyClass
{
void Caller()
{
ulong val = 0;
this.GetValue(ref val);
}
void GetValue(ulong val)
{
VendorLib v = new VendorLib();
v.GetVal(ref val);
}
}
class MyClassBool : IMyClass
{
void Caller()
{
bool val = false;
this.GetValue(ref val);
}
void GetValue(bool val)
{
VendorLib v = new VendorLib();
v.GetVal(ref val);
}
}
public interface IMyClass
{
void Caller();
}
Then any code invoking Caller() would be written against IMyClass, and therefore wouldn't care which implementation you used.
public void CallIt(IMyClass myClass)
{
myClass.Caller();
}
There are lots of patterns to get round this type of problem. For a better understanding you really need to spend a good deal of time reading about OOP in C#, and spend time coding.

Wrapping a class while still exposing all its public methods, properties and fields

I'm trying to make a generic wrapper class that can wrap any other class and add extra functionality to it. However at the same time I want to be able to use this wrapper everywhere where I would normally use the wrapped class. Currently I use implicit casting which works OK. But in an ideal world I would like to the wrapper class to have the same exposed methods and fields as the wrapped class, like in this piece of example code:
class Foo
{
public int Bar() { return 5; }
}
class Wrapper<T>
{
private T contents;
public void ExtraFunctionality() { }
public static implicit operator T(Wrapper<T> w) { return w.contents; }
}
Foo f = new Foo();
Wrapper<Foo> w = new Wrapper<Foo>(foo);
int y = w.Bar();
Can I use some ancient witchcraft, reflection, or other trickery to make this possible?
Note: in C++ I would just overload the -> operator to operate on the field contents instead of on the wrapper.
I wouldn't recommend this, but since you've mentioned witchcraft... you can use dynamic typing with DynamicObject. The wrapper tries to handle the requested method. If it can't, it forwards the call to the underlying wrapped object:
class DynamicWrapper : DynamicObject
{
private readonly object _contents;
public DynamicWrapper(object obj)
{
_contents = obj;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (binder.Name == "ExtraFunctionality")
{
// extra functionality
return true;
}
var method = _contents.GetType()
.GetRuntimeMethods()
.FirstOrDefault(m => m.Name == binder.Name);
if (method == null)
{
result = null;
return false;
}
result = method.Invoke(_contents, args);
return true;
}
}
Edit:
Nevermind, I just noticed you wanted to use an instance of this everywhere where you would normally use an instance of the wrapped type.
You'd have to change the field/property/variable declaration to dynamic to use this.
You can generate the type(s) dynamically using the classes in the System.Reflection.Emit namespace. This link can give you a good starting point.

Problem in using C# generics with method overloading

I am trying to call an overloaded method based on the generic type. I've been doing this in C++ without any pain. But I really don't understand why am not able to do this in C# with generics. Can anybody help me how can I achieve this in C# with generics?
class Test<T>
{
public T Val;
public void Do(T val)
{
Val = val;
MainClass.Print(Val);
}
}
class MainClass
{
public static void Print(UInt16 val)
{
Console.WriteLine("UInt16: " + val.ToString());
}
public static void Print(UInt32 val)
{
Console.WriteLine("UInt32: " + val.ToString());
}
public static void Print(UInt64 val)
{
Console.WriteLine("UInt64: " + val.ToString());
}
public static void Main (string[] args)
{
Test<UInt16> test = new Test<UInt16>();
test.Do(0);
}
}
This won't work because C# generics are fundamentally different to C++ templates. .NET generic class instantiations are created at run-time, whereas C++ template instantiations are created at compile-time (as far as I know; my C++ is very rusty). The generic Do<T> method has to know at compile time a single method to call that can be baked into the resulting IL.
The way to accomplish this is to use reflection, or dynamic (new in C#4):
class Test<T>
{
public T Val;
public void Do(T val)
{
Val = val;
dynamic dynVal = Val;
MainClass.Print(dynVal);
}
}
With dynamic, the method lookup will be at runtime. Note that this is completely separate to generics, and will work equally well in non-generic code.
I might be missing something, but in your code you have:
public void Do(T val)
{
Val = val;
MainClass.Print(Val);
}
and in you main method you have:
test.Do(); //no parameter provided.
The problem youre encountering is that C# desn't select the appropriate method based on your type T. You'll have to make a workaound like this:
void Print<T>(T val)
{
switch(val.GetType())
{
case typeof(UInt64):
Console.WriteLine(...); break;
}
}

Why can't I implicitly cast a Delegate with Extension methods?

I'm trying to figure out a way to automatically cast something to an Action or Func and the best I can come up with is something like this:
[TestFixture]
public class ExecutionTest
{
public void BadMethod()
{
throw new Exception("Something bad happened");
}
[Test]
public void TestBadMethod()
{
// Want this, but it won't work!!
// BadMethod.Execute().IgnoreExceptions();
// Ick
((Action)BadMethod).Exec().IgnoreExceptions();
// Still ick
((Action)BadMethod).IgnoreExceptions();
// Do not want
ExtensionMethods.Exec(BadMethod).IgnoreExceptions();
// Better but still meh
this.Exec(BadMethod).IgnoreExceptions();
}
}
public static class ExtensionMethods
{
public static Action Exec(this Action action)
{ return action; }
public static Action Exec(this object obj, Action action)
{ return action; }
public static void IgnoreExceptions(this Action action)
{
try { action(); }
catch {}
}
}
There has to a better/easier way to do this, any thoughts?
In C#, when you use the method name without parenthesis, it's called a method group and it has no representation other than at compile time. A method group can represent more than one method (because of overloads and overrides), therefore to implicitly identify which method is needed, a target delegate type must be provided.
In your case, you are wondering why the extension method parameter type won't trigger the resolution of the function. Simply put, extension are evaluated after the type is known, that is, the this parameter can't be used as an implicit conversion target.
Example of why it would break:
class Test
{
void M (void) // Fits Action delegate
{
}
int M (int) // Fits Func<int,int> delegate
{
return 5;
}
void Test()
{
M.Exec(); // UHOH!!! Which Exec to resolve to ???
}
}
public static class Extensions
{
public static void Exec(this Action action) { }
public static void Exec(this Func<int, int> func) { }
}
As you can see, there is a conflict, but as a matter of fact, the conflict never happens because C# won't even try to find a matching extension with a method group.
Note how this won't work either:
class A
{
public static implicit operator int (A a)
{
return 5;
}
void F()
{
A a = new A();
a.Blah(); // Error! It won't implicitly try C.Blah()
}
}
public static class C
{
public static void Blah (int i)
{
}
}
C# won't match A to C.Blah(int) because it would require an implicit conversion.
As Coincoin says, it's not gonna work well in C# because of the overzealous love for method overloading. The only workaround I've seen people use is to create Action and Func methods:
public Action Action(Action f) { return f; }
public Action<A> Action<A>(Action<A> f) { return f; }
...
public Func<A,B,C,D,E> Func(Func<A,B,C,D,E> f) { return f; }
You could even call them all "F" to get some sort of short syntax:
F(BadMethod).NoExceptions();
You might decide to not define these methods in your class, and put them in a Funcs utility or something. Alias it with F and it doesn't end up too bad:
F.F(BadMethod).NoException();
But overall it still sucks :(.
F# lets you do this kind of thing very naturally by providing a much better type inference system.

How to do template specialization in C#

How would you do specialization in C#?
I'll pose a problem. You have a template type, you have no idea what it is. But you do know if it's derived from XYZ you want to call .alternativeFunc(). A great way is to call a specialized function or class and have normalCall return .normalFunc() while have the other specialization on any derived type of XYZ to call .alternativeFunc(). How would this be done in C#?
In C#, the closest to specialization is to use a more-specific overload; however, this is brittle, and doesn't cover every possible usage. For example:
void Foo<T>(T value) {Console.WriteLine("General method");}
void Foo(Bar value) {Console.WriteLine("Specialized method");}
Here, if the compiler knows the types at compile, it will pick the most specific:
Bar bar = new Bar();
Foo(bar); // uses the specialized method
However....
void Test<TSomething>(TSomething value) {
Foo(value);
}
will use Foo<T> even for TSomething=Bar, as this is burned in at compile-time.
One other approach is to use type-testing within a generic method - however, this is usually a poor idea, and isn't recommended.
Basically, C# just doesn't want you to work with specializations, except for polymorphism:
class SomeBase { public virtual void Foo() {...}}
class Bar : SomeBase { public override void Foo() {...}}
Here Bar.Foo will always resolve to the correct override.
Assuming you're talking about template specialization as it can be done with C++ templates - a feature like this isn't really available in C#. This is because C# generics aren't processed during the compilation and are more a feature of the runtime.
However, you can achieve similar effect using C# 3.0 extension methods. Here is an example that shows how to add extension method only for MyClass<int> type, which is just like template specialization. Note however, that you can't use this to hide default implementation of the method, because C# compiler always prefers standard methods to extension methods:
class MyClass<T> {
public int Foo { get { return 10; } }
}
static class MyClassSpecialization {
public static int Bar(this MyClass<int> cls) {
return cls.Foo + 20;
}
}
Now you can write this:
var cls = new MyClass<int>();
cls.Bar();
If you want to have a default case for the method that would be used when no specialization is provided, than I believe writing one generic Bar extension method should do the trick:
public static int Bar<T>(this MyClass<T> cls) {
return cls.Foo + 42;
}
I was searching for a pattern to simulate template specialization, too. There are some approaches which may work in some circumstances. However what about the case
static void Add<T>(T value1, T value2)
{
//add the 2 numeric values
}
It would be possible to choose the action using statements e.g. if (typeof(T) == typeof(int)). But there is a better way to simulate real template specialization with the overhead of a single virtual function call:
public interface IMath<T>
{
T Add(T value1, T value2);
}
public class Math<T> : IMath<T>
{
public static readonly IMath<T> P = Math.P as IMath<T> ?? new Math<T>();
//default implementation
T IMath<T>.Add(T value1, T value2)
{
throw new NotSupportedException();
}
}
class Math : IMath<int>, IMath<double>
{
public static Math P = new Math();
//specialized for int
int IMath<int>.Add(int value1, int value2)
{
return value1 + value2;
}
//specialized for double
double IMath<double>.Add(double value1, double value2)
{
return value1 + value2;
}
}
Now we can write, without having to know the type in advance:
static T Add<T>(T value1, T value2)
{
return Math<T>.P.Add(value1, value2);
}
private static void Main(string[] args)
{
var result1 = Add(1, 2);
var result2 = Add(1.5, 2.5);
return;
}
If the specialization should not only be called for the implemented types, but also derived types, one could use an In parameter for the interface. However, in this case the return types of the methods cannot be of the generic type T any more.
By adding an intermediate class and a dictionary, specialization is possible.
To specialize on T, we create an generic interface, having a method called (e.g.) Apply. For the specific classes that interface is implemented, defining the method Apply specific for that class. This intermediate class is called the traits class.
That traits class can be specified as a parameter in the call of the generic method, which then (of course) always takes the right implementation.
Instead of specifying it manually, the traits class can also be stored in a global IDictionary<System.Type, object>. It can then be looked up and voila, you have real specialization there.
If convenient you can expose it in an extension method.
class MyClass<T>
{
public string Foo() { return "MyClass"; }
}
interface BaseTraits<T>
{
string Apply(T cls);
}
class IntTraits : BaseTraits<MyClass<int>>
{
public string Apply(MyClass<int> cls)
{
return cls.Foo() + " i";
}
}
class DoubleTraits : BaseTraits<MyClass<double>>
{
public string Apply(MyClass<double> cls)
{
return cls.Foo() + " d";
}
}
// Somewhere in a (static) class:
public static IDictionary<Type, object> register;
register = new Dictionary<Type, object>();
register[typeof(MyClass<int>)] = new IntTraits();
register[typeof(MyClass<double>)] = new DoubleTraits();
public static string Bar<T>(this T obj)
{
BaseTraits<T> traits = register[typeof(T)] as BaseTraits<T>;
return traits.Apply(obj);
}
var cls1 = new MyClass<int>();
var cls2 = new MyClass<double>();
string id = cls1.Bar();
string dd = cls2.Bar();
See this link to my recent blog and the follow ups for an extensive description and samples.
I think there is a way to achieve it with .NET 4+ using dynamic resolution:
static class Converter<T>
{
public static string Convert(T data)
{
return Convert((dynamic)data);
}
private static string Convert(Int16 data) => $"Int16 {data}";
private static string Convert(UInt16 data) => $"UInt16 {data}";
private static string Convert(Int32 data) => $"Int32 {data}";
private static string Convert(UInt32 data) => $"UInt32 {data}";
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Converter<Int16>.Convert(-1));
Console.WriteLine(Converter<UInt16>.Convert(1));
Console.WriteLine(Converter<Int32>.Convert(-1));
Console.WriteLine(Converter<UInt32>.Convert(1));
}
}
Output:
Int16 -1
UInt16 1
Int32 -1
UInt32 1
Which shows that a different implementation is called for different types.
Some of the proposed answers are using runtime type info: inherently slower than compile-time bound method calls.
Compiler does not enforce specialization as well as it does in C++.
I would recommend looking at PostSharp for a way to inject code after the usual compiler is done to achieve an effect similar to C++.
A simpler, shorter and more readable version of what #LionAM proposed (about half of the code size), shown for lerp since this was my actual use case:
public interface ILerp<T> {
T Lerp( T a, T b, float t );
}
public class Lerp : ILerp<float>, ILerp<double> {
private static readonly Lerp instance = new();
public static T Lerp<T>( T a, T b, float t )
=> ( instance as ILerp<T> ?? throw new NotSupportedException() ).Lerp( a, b, t );
float ILerp<float>.Lerp( float a, float b, float t ) => Mathf.Lerp( a, b, t );
double ILerp<double>.Lerp( double a, double b, float t ) => Mathd.Lerp( a, b, t );
}
You can then just e.g.
Lerp.Lerp(a, b, t);
in any generic context, or provide the method as a grouped Lerp.lerp method reference matching T(T,T,float) signature.
If ClassCastException is good enough for you, you can of course just use
=> ( (ILerp<T>) instance ).Lerp( a, b, t );
to make the code even shorter/simpler.
If you just want to test if a type is derrived from XYZ, then you can use:
theunknownobject.GetType().IsAssignableFrom(typeof(XYZ));
If so, you can cast "theunknownobject" to XYZ and invoke alternativeFunc() like this:
XYZ xyzObject = (XYZ)theunknownobject;
xyzObject.alternativeFunc();
Hope this helps.

Categories

Resources