Anonymous method shortest syntax - c#

Regarding anonymous methods, and given a method "WriteConditional" that has the first parameter as a Func, is there a way to even eliminate the extra "() => " syntax?
It seems like you should be able to, since its unambiguous as long as there's no additional overload that would accept string, right?
void Program()
{
IDictionary<string,string> strings = new Dictionary<string,string>() { {"test","1"},{"test2","2"}};
//seems like this 'should' work, because WriteConditional has no other overload
//that could potentially make this ambiguous
WriteConditional(strings["test"],"<h3>{0}</h3>");
//since WriteConditional_2 has two overloads, one that has Func<string> and another with string,
//the call could be ambiguous, so IMO you'd definitely have to "declare anonymous" here:
WriteConditional_2(()=>strings["test"],"<h3>{0}</h3>");
}
void WriteConditional(Func<string> retriever, string format)
{
string value = retriever.Invoke();
if(string.IsNullOrEmpty(value)==false)
Console.WriteLine(string.Format(format,value));
}
void WriteConditional_2(Func<string> retriever, string format)
{
string value = retriever.Invoke();
if(string.IsNullOrEmpty(value)==false)
Console.WriteLine(string.Format(format,value));
}
void WriteConditional_2(string value, string format)
{
if(string.IsNullOrEmpty(value)==false)
Console.WriteLine(string.Format(format,value));
}

No, there is no such way. You could however, cheat and provide your own overload:
void WriteConditional(Func<string> retriever, string format)
{
var value = retriever();
if(string.IsNullOrEmpty(value)==false)
Console.WriteLine(string.Format(format,value));
}
void WriteConditional(string value, string format)
{
WriteConditional(() => value, format);
}

is there a way to even eliminate the extra "() => " syntax?
I also think the answer is no but you can do something if your func returns a custom class by using operator overloading.
This could be possible for other types if you could use operation overloading with extention methods
using System;
public class MyClass
{
public static implicit operator Func<MyClass>(MyClass obj)
{
return () => { Console.WriteLine("this is another cheat"); return new MyClass(); };
}
}
public class Program
{
static void Main(string[] args)
{
MyClass x = new MyClass();
WriteConditional(x);
Console.ReadLine();
}
static void WriteConditional(Func<MyClass> retriever) { }
}

Related

System.Reflection.TargetParameterCountException when Parameter count can be dynamic

All methods in the "ProbabilitiesTheory" class accept dynamic count of parameters - it means that there can be put as many parameters as one wants. But .NET still says "System.Reflection.TargetParameterCountException" when invoking a method, that has "params" keyword in its parameters.
Here's the code:
internal static class ProbabilitiesTheory
{
static public double GetMediumValue(params double[] integers)
{ }
}
class Program
{
static void Main(string[] args)
{
MethodInfo[] methods = Type.GetType("ConsoleApplication1.ProbabilitiesTheory").GetMethods();
while (true)
{
Console.WriteLine("Write the name of the method\n");
string NameOfMethod = Console.ReadLine();
Console.WriteLine("Write the parameters of the method using the following format:
parameter1;parameter2;parameter3;parameterN\n");
string ParametersOfMethod = Console.ReadLine();
foreach (var i in methods)
{
if (i.Name == NameOfMethod)
{
object[] #parameters = (from t in ParametersOfMethod.Split(';') where t != "" select (object)Convert.ToDouble(t)).ToArray();
i.Invoke(null, #parameters); // Exception HERE
}
}
Console.WriteLine("______");
}
}
}
It is absolutely ok with LINQ expression there, i get what i need to get: object[] containing dynamic amount of double values.
How do i solve this problem?
As far as reflection is concerned, a params array is just an array with a fancy syntactical sugar. You could solve the immediate problem for most of your methods by adjusting your code like so:
double[] #parameters = (from t in ParametersOfMethod.Split(';') where t != "" select Convert.ToDouble(t)).ToArray();
i.Invoke(null, new[] { #parameters});
The gist of this is that a params array is just a single parameter at run-time, and the ability to add a variable amount of values to it is just a nicety done by the compiler.
You can confirm this with a snippet like this:
void Main()
{
var parameterCount = typeof(Test).GetMethod("Foo").GetParameters().Count();
Console.WriteLine(parameterCount); // Output: 2
}
// Define other methods and classes here
public static class Test
{
public static void Foo(double x, params double[] y)
{}
}
If you need to invoke a function that uses a params array with user provided values when the params array is not the only parameter, you're going to need to get the method parameter count and work out where the array actually starts, then wrap things accordingly.

Can I create a Dictionary of Funcs that vary in their first argument?

I have a bunch of static methods that all have the same signature, except for the type of their first argument, for example:
public static class ElementCreators
{
public static XmlElement CreateElementForString
(string s, string name, string namespaceURI)
{
[...]
}
public static XmlElement CreateElementForDecimal
(Decimal d, string name, string namespaceURI)
{
[...]
}
}
I want to create a Dictionary (or some sort of lookup that can be modified at runtime - people are supposed to be able to add their own funcs, though once a func is added, it doesn't need to be modified/removed, and there are never two+ funcs for a given type. There might be funcs for base and derived types, but in that case, it's up to the user to register them e.g., in the right order) to dispatch based on the type, e.g.:
var funcs = new Dictionary<Type, Func<object, string, string, XmlElement>>();
funcs[typeof(string)] = ElementCreators.CreateElementForString;
funcs[typeof(Decimal)] = ElementCreators.CreateElementForDecimal;
Now, this doesn't work, as there is no contravariance between delegates, so the compiler complains that CS0123 No overload for 'CreateElementForString' matches delegate 'Func<object, string, string, XmlElement>'.
One option is to create another delegate as the middle-man:
funcs[typeof(string)] =
(o,s1,s2) => ElementCreators.CreateElementForString((string)o, s1, s2);
That works, but is a) ugly and b) introduces a bunch of unnecessary delegates.
Generics don't seem to be an option, because the Func can not be of an open type T. Similarly, dynamic doesn't work, but I don't want to use these anyway (runtime cost).
I could introduce a level of indirection for each method, which avoids the delegate, but it isn't any less ugly:
public static XmlElement CreateElementForString(object s, string name, string namespaceURI)
=> CreateElementForString((string)s, name, namespaceURI);
And of course, I could try automating something like that (T4 templates, Pre-Build task, custom Build Action, etc.)
But before I do that, I wonder if there's a better way that I've overlooked?
Visual Studio 2017, .NET 4.7.1, and C# 7.2 are all available for this.
As the comments cover, not really. But you can build a class that accomplishes what you want (relatively type safe, pleasant to use) I think.
public class DelegateDictionary
{
Dictionary<Type, Delegate> Lookup;
public DelegateDictionary()
{
Lookup = new Dictionary<System.Type, Delegate>();
}
public void Add<T>(Func<T, string, string, XmlElement> mtd)
{
Lookup.Add(typeof(T), mtd);
}
public XmlElement Invoke<T>(T value, string name, string namespaceURI)
{
if (!Lookup.TryGetValue(typeof(T), out var del)) throw new InvalidOperationException($"No delegate registered for {typeof(T).Name}");
var typedDel = (Func<T, string, string, XmlElement>)del;
return typedDel(value, name, namespaceURI);
}
}
You do have to type the Add(...) call, it can't be inferred), but the Invoke(...) can be inferred (and presumably there are more invocations than registrations).
// example usage
{
var dict = new DelegateDictionary();
dict.Add<string>(ElementCreators.CreateElementForString);
dict.Add<Decimal>(ElementCreators.CreateElementForDecimal);
dict.Invoke("stringValue", "myName", "what-even-is-a-namespace");
dict.Invoke(1.0m, "myName", "what-even-is-a-namespace");
}
I don't think you'll pay for anything besides the cast on invoke, but haven't profiled to confirm.
If you can be whole program static/global then you can use a very fast compile time dictionary (no-lookup) and generics (no boxing):
class Program
{
void Main()
{
// Set up defaults; lambda rather than Method group (allocs)
ElementCreators<string>.CreateElement = (s, name, namespaceURI)
=> ElementCreators.CreateElement(s, name, namespaceURI);
ElementCreators<Decimal>.CreateElement = (d, name, namespaceURI)
=> ElementCreators.CreateElement(d, name, namespaceURI);
// Call
XmlElement xml = ElementCreators<string>.CreateElement("hello", "name", "ns");
}
}
public static class ElementCreators<T>
{
// Can change property get to throw KeyNotFound if null
public static Func<T, string, string, XmlElement> CreateElement { get; set; }
}
public static class ElementCreators
{
public static XmlElement CreateElement(string s, string name, string namespaceURI)
{
return null;
}
public static XmlElement CreateElement(Decimal d, string name, string namespaceURI)
{
return null;
}
}

Extension methods with type name as `this` parameter, e.g. int?.TryParse(“32”)

I want to write an extension method for nullable int so that I could write the code int?.TryParse(“32”) in a similar manner to writing int.TryParse(“32”). The following method signature is not valid:
public static int? TryParse(this Type(int?), string input)
{
...
}
Is there any solution?
public static int? TryParse(this string input) {
int i;
return int.TryParse(input, out i) ? i : (int?)null;
}
Usage:
var i = yourString.TryParse();
I think you may want to define a generic method like this:
public static T? TryParse<T>(this string input) where T : struct {
T i = default(T);
object[] args = new object[] { input, i };
var tryParse = typeof(T).GetMethod("TryParse",
new[] { typeof(string), typeof(T).MakeByRefType() });
if(tryParse != null){
var r = (bool) tryParse.Invoke(null, args);
return r ? (T) args[1] : (T?)null;
}
return (T?)null;
}
//Usage
double? d = yourString.TryParse<double>();
int? i = yourString.TryParse<int>();
Using the generic method above is very convenient but the performance may be reduced a little due to using reflection. If you just want some TryParse methods for some types int, double, ... You should define particular method for each one, named them differently like TryParseInt, TryParseDouble, TryParseDecimal, ... and apply the similar code to the first code snippet I posted above.
Extension methods look like instance methods, but are in fact static methods. When you define an extension method, you can extend instances of a class with a new method, but you cannot extend the class itself with a new static method.

Overloading methods in C# .NET

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

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.

Categories

Resources