I am stuck on a problem. I found out that there is no implicit conversion from Func<int> to Func<object> and then especially not from generic Func<T>. I sort of understand why there is no conversion. But I still need to store any functions like the following:
static Dictionary<int, Func<int, object>> funcs = new Dictionary<int, Func<int, object>>();
public static void SetFunction<T>(Func<int, T> f)
{
funcs[42] = f;
}
public static void Main()
{
SetFunction(x => 42);
SetFunction(x => "42");
SetFunction(x => Guid.NewGuid());
}
Is there any way around to store these functions? I don't want to use dynamic.
Also I need to keep original functions. To call them multiple times.
You couldn't use dynamic anyway, it's not what it's for. Instead of thinking about casting, simply add another layer to your function:
public static void SetFunction<T>(Func<T> f)
{
funcs[42] = () => (object)f();
}
You can probably avoid using generics altogether.
static Dictionary<int, Func<object>> funcs = new Dictionary<int, Func<object>>();
public static void SetFunction(Func<object> f)
{
funcs[42] = f;
}
public static void Main()
{
SetFunction(() => 42);
SetFunction(() => "42");
SetFunction(() => Guid.NewGuid());
}
I build an answer based on yours. Especially Blindy's.
I needed some reasoning but you enlightened me enough to build it.
static Dictionary<int, Func<object>> funcs = new Dictionary<int, Func<object>>();
static Random rnd = new Random();
public static void SetFunction<T>(int index, Func<Random, T> f)
{
funcs[index] = () => (object)f(rnd);
}
public static void Main()
{
SetFunction(41, x => x.NextDouble());
SetFunction(42, x => x.Next());
SetFunction(43, _ => "HW");
Console.WriteLine(funcs[41]());
Console.WriteLine(funcs[41]());
Console.WriteLine(funcs[42]());
Console.WriteLine(funcs[42]());
Console.WriteLine(funcs[43]());
Console.WriteLine(funcs[43]());
}
Output:
0.6657498062894446
0.5739200415899605
1762534382
1301357548
HW
HW
Related
Is it possible to achieve having typed func in a dict, with different types as keys and no casting in the func.
Something like this:
class Program
{
class Person
{
public int Id { get; set; }
}
class Dog
{
public string Name { get; set; }
}
static void Main(string[] args)
{
var funcDict = new Dictionary<Type, Func<object, object, bool>>()
{
{typeof(Person), (Person p1, Person p2) => p1.Id == p2.Id},
{typeof(Dog), (Dog d1, Dog d2) => d1.Name == d2.Name},
};
var p1 = new Person()
{
Id = 4
};
var p2 = new Person();
Console.WriteLine(funcDict[p1.GetType()].Invoke(p1, p2));
}
}
Best I can come up with is creating the funcs with object types and then casting in the func body, but if possible would like to avoid that, cause it would make for a much cleaner API.
var funcDict = new Dictionary<Type, Func<object, object, bool>>()
{
{typeof(Person), (o1, o2) => ((Person) o1).Id == ((Person) o2).Id},
};
Short answer would be no, not unless you use dynamic typing. But you could hide the ugliness:
public class FunctionDictionary
{
private Dictionary<Type, object> dict = new Dictionary<Type, object>();
public void Add<T>(Func<T, T, bool> method) => dict.Add(typeof(T), method);
public bool Run<T>(T a, T b) => ((Func<T, T, bool>)dict[typeof(T)]).Invoke(a, b);
}
disclaimer: No error handling, not tested.
You could replace "object" with "dynamic" in the example above to get rid of the cast. But I would probably not, since it would probably be a bit slower, and not much easier to read.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I know this topic (memoization) has been discussed quite a bit (like here), but no answer I could find satisfies the DRY principle as much as I would like, so please, read this whole question and the three points I want to address.
I have a simple support class like this:
public class Memoized<T1, TResult>
{
private readonly Func<T1, TResult> _f;
private readonly Dictionary<T1, TResult> _cache = new Dictionary<T1, TResult>();
public Memoized(Func<T1, TResult> f)
{
_f = f;
}
public TResult Invoke(T1 p1)
{
if (p1 == null) throw new ArgumentNullException(nameof(p1));
if (_cache.TryGetValue(p1, out var res)) return res;
return _cache[p1] = _f(p1);
}
public static Func<T1, TResult> Of(Func<T1, TResult> f)
{
var memo = new Memoized<T1, TResult>(f);
return x => memo.Invoke(x);
}
}
Nothing especially fancy, but it allows me to do this:
public class MyClass
{
public Func<int, bool> MemoizedMethod { get; }
private bool UncachedMethod(int v)
{
return v > 0;
}
public MyClass()
{
MemoizedMethod = Memoized<int, bool>.Of(UncachedMethod);
}
}
Now, even if the resulting code is not terribly noisy, I'm trying to figure out if the implementation could be more elegant, because currently I need:
an invokable property that acts as a Method.
a true method that should not be called directly.
a line in the constructor (cannot be an inline initialization) that links the two (with a third repetition of the function signature!).
Any suggestion for a strategy that allows to remove one (or two!) of the above points would be great.
In my struggle for elegance, I finally found what I think is the best syntax I saw anywhere:
private class MemoizedTest
{
private int _counter = 0;
public int Method(int p) => this.Memoized(p, x =>
{
return _counter += x;
});
}
Implementation (one pretty small extension class):
namespace System
{
public static class MemoizerExtension
{
internal static ConditionalWeakTable<object, ConcurrentDictionary<string, object>> _weakCache =
new ConditionalWeakTable<object, ConcurrentDictionary<string, object>>();
public static TResult Memoized<T1, TResult>(
this object context,
T1 arg,
Func<T1, TResult> f,
[CallerMemberName] string? cacheKey = null)
where T1 : notnull
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (cacheKey == null) throw new ArgumentNullException(nameof(cacheKey));
var objCache = _weakCache.GetOrCreateValue(context);
var methodCache = (ConcurrentDictionary<T1, TResult>) objCache
.GetOrAdd(cacheKey, _ => new ConcurrentDictionary<T1, TResult>());
return methodCache.GetOrAdd(arg, f);
}
}
}
Explanation
In the implementation I'm using a ConditionalWeakTable for caching, effectively extending the internal structure of the object invoking the memoization. As an additional key, the CallerMemberName is used, acting as a second key (this allows more memoizations for instance, and optionally more memoizations per method, if passing the cacheKey parameter explicitly).
The third key is the parameter of the invocation.
So, we have 3 runtime dictionary-like searches instead of 1, but a syntax that is a lot cleaner, IMO.
Is it worth it? I dunno, but my desire for elegance is satiated.
If someone else is interested, I'm including the tests for reference:
[TestFixture]
public class MemoizerTest
{
[Test]
public void MemoizationWorksOnFuncs()
{
int counter = 0;
Func<int, int> f = x => counter += x;
Assert.That(this.Memoized(1, f), Is.EqualTo(1));
Assert.That(this.Memoized(2, f), Is.EqualTo(3));
Assert.That(this.Memoized(2, f), Is.EqualTo(3));
Assert.That(this.Memoized(1, f), Is.EqualTo(1));
}
private class MemoizedTest
{
private int _counter = 0;
public int Method(int p)
=> this.Memoized(p, x => { return _counter += x; });
}
[Test]
public void MemoizationWorksOnInstances()
{
var obj1 = new MemoizedTest();
Assert.That(obj1.Method(5), Is.EqualTo(5));
Assert.That(obj1.Method(4), Is.EqualTo(9));
Assert.That(obj1.Method(5), Is.EqualTo(5));
Assert.That(obj1.Method(1), Is.EqualTo(10));
Assert.That(obj1.Method(4), Is.EqualTo(9));
obj1 = new MemoizedTest();
Assert.That(obj1.Method(5), Is.EqualTo(5));
Assert.That(obj1.Method(4), Is.EqualTo(9));
Assert.That(obj1.Method(5), Is.EqualTo(5));
Assert.That(obj1.Method(1), Is.EqualTo(10));
Assert.That(obj1.Method(4), Is.EqualTo(9));
}
[Test]
[Ignore("This test passes only when compiled in Release mode")]
public void WeakMemoizationCacheIsCleared()
{
var obj1 = new MemoizedTest();
var r1 = obj1.Method(5);
MemoizerExtension._weakCache.TryGetValue(obj1, out var cache);
var weakRefToCache = new WeakReference(cache);
cache = null;
GC.Collect(2);
obj1 = null;
GC.Collect();
GC.Collect();
var msg = weakRefToCache.TrackResurrection;
Assert.That(weakRefToCache.IsAlive, Is.False, "The weak reference should be dead.");
Assert.That(r1, Is.EqualTo(5));
}
}
If you capture the dictionary in the lambda, your state will be maintained implicitly.
public class Memoized
{
// Example with a single parameter. That parameter becomes the key to the dictionary.
public static Func<T1, TRet> Of<T1, TRet>(Func<T1, TRet> f)
{
ConcurrentDictionary<T1, TRet> cache = new ConcurrentDictionary<T1, TRet>();
return (arg1) => cache.GetOrAdd(arg1, xarg=>f(xarg));
}
// Example with two parameters. The key is a tuple, and it must be unpacked before calling func.
// Three or more parameters generalize from this
public static Func<T1, T2, TRet> Of<T1, T2, TRet>(Func<T1, T2, TRet> f)
{
ConcurrentDictionary<Tuple<T1,T2>, TRet> cache = new ConcurrentDictionary<Tuple<T1, T2>, TRet>();
return (arg1, arg2) => cache.GetOrAdd(new Tuple<T1,T2>(arg1, arg2),
(xarg)=>f(xarg.Item1, xarg.Item2)
);
}
}
Usage example:
class Test
{
public int Method(String s, String s2)
{
return 99;
}
}
class Program
{
static bool UncachedMethod(int x) { return x > 0; }
static void Main(string[] args)
{
var cached = Memoized.Of<int,bool>(UncachedMethod);
var exampleCall = cached(44);
var exampleCall2 = cached(44);
// Capture a non-static member function
var x = new Test();
var cachedX = Memoized.Of<String, String,int>(x.Method);
var exampleCall3 = cachedX("a","b");
}
}
I need some store where I can register some callback for automatically update.
class Store
{
readonly Dictionary<Type, Action<dynamic>> _callbacks = new Dictionary<Type, Action<dynamic>>();
public void Register<T>(Action<T> updateCallback)
{
_callbacks.Add(typeof(T), value => updateCallback(value));
}
public void Save<T>(T value)
{
_callbacks[typeof(T)](value);
}
}
class Program
{
private static string _stringField = "0";
private static int _intField = 0;
static void Main(string[] args)
{
var store = new Store();
store.Register<string>(value => _stringField = value);
store.Register<int>(value => _intField = value);
Console.WriteLine($"{_stringField}/{_intField}");
store.Save("5");
Console.WriteLine($"{_stringField}/{_intField}");
store.Save(7);
Console.WriteLine($"{_stringField}/{_intField}");
}
}
Output:
0/0 5/0 5/7
It works fine. I just don't like Action<dynamic> in Dictionary. Firstly it looks as a hack. Secondary it produces box operation in Save method, because of dynamic. I understand that I can't use only generics because I'm not in static context but I'm looking for a best solution for this sample. Please advise some code without changing of Program class. So I need to register something one time and it will be updated automatically each time of Save method call.
If you don't like dynamic, you can store your callbacks as Action<object>, like this:
class Store {
readonly Dictionary<Type, Action<object>> _callbacks = new Dictionary<Type, Action<object>>();
public void Register<T>(Action<T> updateCallback) {
// cast here
_callbacks.Add(typeof(T), value => updateCallback((T) value));
}
public void Save<T>(T value) {
_callbacks[typeof(T)](value);
}
}
Use Delegate, so Dictionary<Type, Delegate> is good enough
Delegate d = _callbacks[typeof(T)];
Action<T> action = (Action < T >)d;
Storing
delegates in collections is normal practice (not a hack)
Boxing to object is imperfect practice
LINQ allows to elegantly transform the collection returned by a method to a different collection, i.e.
var x = SomeMethod().Select(t => new { ... });
Now, is there a concise way in C# to transform the return value of a method without introducing an intermediary variable? Declaring and invoking a lambda seems to work but is quite ugly:
var x = new Func<T, object>(t => { return new { ... }; })(SomeMethod());
Am I missing something obvious or is this the best one can do with C# today?
You can apply Select followed by Single to sequence of one item created from the result of calling SomeMethod, as follows:
var x = Enumerable.Repeat(SomeMethod(), 1).Select(r => new {...}).Single();
If you do it a lot, you can make a generic extension method for this:
static class MyExtensions {
public static TRes Transform<TSrc,TRes>(this TSrc src, Func<TSrc,TRes> selector) {
return selector(src);
}
}
Now the syntax becomes very simple:
var res = SomeMethod().Transform(x => new { ... });
I just figured that a generic extension method could fill the gap:
public static class TransformExtension
{
public static T2 Transform<T1, T2>(this T1 t1, Func<T1, T2> transform)
{
return transform(t1);
}
}
Sample usage:
public class A { };
public class B { };
void Foo()
{
var a = new A();
var b = a.Transform(x => new B());
}
Happy to hear why that's possibly a terrible idea.
I have code:
public delegate int SomeDelegate(int p);
public static int Inc(int p) {
return p + 1;
}
I can cast Inc to SomeDelegate or Func<int, int>:
SomeDelegate a = Inc;
Func<int, int> b = Inc;
but I can't cast Inc to SomeDelegate and after that cast to Func<int, int> with usual way like this:
Func<int, int> c = (Func<int, int>)a; // Сompilation error
How I can do it?
There's a much simpler way to do it, which all the other answers have missed:
Func<int, int> c = a.Invoke;
See this blog post for more info.
SomeDelegate a = Inc;
Func<int, int> b = Inc;
is short for
SomeDelegate a = new SomeDelegate(Inc); // no cast here
Func<int, int> b = new Func<int, int>(Inc);
You can't cast an instance of SomeDelegate to a Func<int, int> for the same reason you can't cast a string to a Dictionary<int, int> -- they're different types.
This works:
Func<int, int> c = x => a(x);
which is syntactic sugar for
class MyLambda
{
SomeDelegate a;
public MyLambda(SomeDelegate a) { this.a = a; }
public int Invoke(int x) { return this.a(x); }
}
Func<int, int> c = new Func<int, int>(new MyLambda(a).Invoke);
Try this:
Func<int, int> c = (Func<int, int>)Delegate.CreateDelegate(typeof(Func<int, int>),
b.Target,
b.Method);
The problem is that:
SomeDelegate a = Inc;
Isn't actually a cast. It's the short-form of:
SomeDelegate a = new SomeDelegate(Inc);
Therefore there's no cast. A simple solution to your problem can be this (in C# 3.0)
Func<int,int> f = i=>a(i);
This works (in C# 4.0 at least - not tried in earlier versions):
SomeDelegate a = Inc;
Func<int, int> c = new Func<int, int>(a);
If you look at the IL, this compiles into exactly the same code as Winston's answer. Here's the IL for the second line of what I just wrote:
ldloc.0
ldftn instance int32 ConsoleApplication1.Program/SomeDelegate::Invoke(int32)
newobj instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object, native int)
And that's also precisely what you see if you assign a.Invoke into c.
Incidentally, although Diego's solution is more efficient, in that the resulting delegate refers directly to the underlying method rather than going through the other delegate, it doesn't handle multicast delegates correctly. Winston's solution does, because it just defers completely to the other delegate. If you want a direct solution that also handles delegates with multiple targets, you need something a little more complex:
public static TResult DuplicateDelegateAs<TResult>(MulticastDelegate source)
{
Delegate result = null;
foreach (Delegate sourceItem in source.GetInvocationList())
{
var copy = Delegate.CreateDelegate(
typeof(TResult), sourceItem.Target, sourceItem.Method);
result = Delegate.Combine(result, copy);
}
return (TResult) (object) result;
}
This does the right thing for delegates with a single target by the way—it will end up producing just a single delegate of the target type that refers directly to whatever method (and where applicable, object) the input delegate referred to.
You can hack a cast by using a trick where you use the c# equivalent of a c++ union. The tricky part is the struct with two members that have a [FieldOffset(0)]:
[TestFixture]
public class Demo
{
public void print(int i)
{
Console.WriteLine("Int: "+i);
}
private delegate void mydelegate(int i);
[StructLayout(LayoutKind.Explicit)]
struct funky
{
[FieldOffset(0)]
public mydelegate a;
[FieldOffset(0)]
public System.Action<int> b;
}
[Test]
public void delegatetest()
{
System.Action<int> f = print;
funky myfunky;
myfunky.a = null;
myfunky.b = f;
mydelegate a = myfunky.a;
a(5);
}
}
It is the same kind of problem as this:
public delegate int SomeDelegate1(int p);
public delegate int SomeDelegate2(int p);
...
SomeDelegate1 a = new SomeDelegate1(Inc);
SomeDelegate2 b = (SomeDelegate2)a; // CS0030
which is the same kind of problem as:
public class A { int prop { get; set; } }
public class B { int prop { get; set; } }
...
A obja = new A();
B objb = (B)obja; // CS0029
Objects cannot be casted from one type to an unrelated other type, even though the types are otherwise completely compatible. For lack of a better term: an object has type identity that it carries along at runtime. That identity cannot be changed after the object is created. The visible manifestation of this identity is Object.GetType().
I like examples. Here is my example code:
class Program
{
class A
{
public A(D d) { d.Invoke("I'm A!"); }
public delegate string D(string s);
}
class B
{
public delegate string D(string s);
}
static void Main(string[] args)
{
//1. Func to delegates
string F(dynamic s) { Console.WriteLine(s); return s; }
Func<string, string> f = F;
//new A(f);//Error CS1503 Argument 1: cannot convert from 'System.Func<string, string>' to 'ConsoleApp3.Program.A.D'
new A(new A.D(f));//I'm A!
new A(x=>f(x));//I'm A!
Func<string, string> f2 = s => { Console.WriteLine(s); return s; };
//new A(f2);//Same as A(f)
new A(new A.D(f2));//I'm A!
new A(x => f2(x));//I'm A!
//You can even convert between delegate types
new A(new A.D(new B.D(f)));//I'm A!
//2. delegate to F
A.D d = s => { Console.WriteLine(s); return s; };
Func<string, string> f3 = d.Invoke;
f3("I'm f3!");//I'm f3!
Func<string, string> f4 = new Func<string, string>(d);
f4("I'm f4!");//I'm f4!
Console.ReadLine();
}
}
The output is: