I have a function that takes a list of Func<bool> each with an attached value. It iterates the list and returns the attached value if a delegate returns true. Some of these delegates call the same function with the same parameters how do I best memoize the result of such calls within the scope of the TryFindValue method?
The return value of the functions may change between calls to TryFindValue, but they will not change while iterating the list. I would like to avoid generating garbage (boxing/unboxing by casting to object for example). Ideally, I would only have to use the space for memoized values in the scope of TryFindValue and not for the entire lifetime of each delegate for example, but I do not know if that is possible.
public class SomeClass
{
public bool TryFindValue(List<CondValue> list, out int value)
{
for (int i = 0; i < list.Count; i++)
{
var condValue = list[i];
if (condValue.cond())
{
value = condValue.value;
return true;
}
}
value = default(int);
return false;
}
}
public class SomeOtherClass
{
private List<CondValue> list;
public SomeOtherClass()
{
list = new List<CondValue>();
// SomeMethod(3) will be calculated twice
list.Add(new CondValue(() => SomeMethod(3) > SomeOtherMethod(), 42));
list.Add(new CondValue(() => SomeMethod(3) < SomeThirdMethod(), 35));
}
private float SomeMethod(int value)
{
// Implementation... (uses some internal or global state)
}
private int SomeOtherMethod()
{
// Implementation... (uses some internal or global state)
}
private int SomeThirdMethod()
{
// Implementation... (uses some internal or global state)
}
}
public struct CondValue
{
public Func<bool> cond;
public int value;
public CondValue(Func<bool> func, int value)
{
this.func = func;
this.value = value;
}
}
If you turn CondValue.cond into an expression tree instead of a Func then maybe you could make some complicated solution. I have no experience doing so and I wouldn't suggest venturing out on that adventure. Apart from that I don't see a good solution to only keep it cached/memorized within the lifetime of a single call to TryFindValue.
I would rather ask you:
Is there any good reason you have the current setup?
It seems like an unnecessarily complicated setup. Since you've only shown a very abstract example it's difficult to suggest a better alternative.
Would e.g. SomeMethod(3) not always return the same value?
You could wrap that method in some caching logic (e.g. with help from PostSharp). But if it doesn't consistently return the same value, you'd have to clear that cache when necessary, which makes it harder to maintain.
Instead of having individual conditions that return true or false with an attached value you could just return the value or null. How does that help? For the following solution, I am assuming that the delegates in the list that call the same function are added to the list together in the same function (here in the constructor SomeOtherClass). From there you could batch together delegates that call the same functions with the same parameters in an if-else if code block and manually "memoize" the result of the function at the top of the delegate.
Delegates that call the same functions with the same parameters smells like they are related in this if-else if relationship anyway. I have added SomeFourthMethod to show how to still compactly add a single conditional individually.
If you have suggestions to improve the details of this solution (using something else than nullable, etc.) then feel free to suggest it in a comment.
If all the conditions are always independent and just happen to sometimes call the same function, then this solution might not be appropriate. Otherwise, it is the simplest most effective solution I can think of.
public class SomeClass
{
public bool TryFindValue(List<Func<int?>> list, out int value)
{
for (int i = 0; i < list.Count; i++)
{
var func = list[i];
int? ret = func();
if (ret.HasValue)
{
value = ret.Value;
return true;
}
}
value = default(int);
return false;
}
}
public class SomeOtherClass
{
private List<Func<int?>> list;
public SomeOtherClass()
{
list = new List<Func<int?>>();
Add(() =>
{
float memoized = SomeMethod(3);
if (memoized > SomeOtherMethod())
return 42;
else if (memoized < SomeThirdMethod())
return 35;
return null;
});
Add(() => SomeFourthMethod() > 4, 72);
}
private void Add(Func<int?> snippet)
{
list.Add(snippet);
}
private void Add(Func<bool> cond, int value)
{
list.Add(() =>
{
if (cond())
return value;
return null;
});
}
private float SomeMethod(int value)
{
// Implementation... (uses some internal or global state)
}
private int SomeOtherMethod()
{
// Implementation... (uses some internal or global state)
}
private int SomeThirdMethod()
{
// Implementation... (uses some internal or global state)
}
private int SomeFourthMethod()
{
// Implementation... (uses some internal or global state)
}
}
Related
I am trying to create a custom dictionary with some methods. I created a struct containing the information for lanes in my game. One information tells me if there is an enemy in the lane(Occupied) and the other if we completed that lane so no more enemies will come there(Completed).
I am able to get the initial information out, but cannot update them with my methods. I construct it by adding all 7 lanes, where none of them are either occupied or completed. Then throughout my game, I would like to mark them either as completed or occupied or free, but even after a lot of time searching around, I couldn't figure out the proper way to call for an update of these items inside my laneInfo property.
public struct laneInfo
{
public bool Occupied;
public bool Completed;
}
public class laneInfoClass : Dictionary<int, laneInfo>
{
public laneInfo laneinfo;
public laneInfoClass()
{
for(int i = 0; i <= 6; i++)
{
this.Add(i, false, false);
}
}
public void Add(int key, bool occupied, bool completed)
{
laneinfo.Occupied = occupied;
laneinfo.Completed = completed;
this.Add(key, laneinfo);
}
public void Complete()
{
laneinfo.Completed = true;
}
public void Occupy()
{
laneinfo.Occupied = true;
}
public void Free()
{
laneinfo.Occupied = false;
}
}
Thanks!
Its fairly rare that your class would inherit from a dictionary/list/collection (why?), more often than not what you are actually modelling is a class which has an instance member which is that same dictionary/list/collection.
In addition, you need some way to notify your class which particular lane you're trying to update, you use an integer key so work with that:
public struct LaneInfo
{
public bool Occupied {get;set;}
public bool Completed {get;set;}
}
public class LaneInfoContainer
{
private Dictionary<int, LaneInfo> laneInfoDict = new Dictionary<int, LaneInfo>();
public LaneInfoContainer()
{
for(int i = 0; i <= 6; i++)
{
this.Add(i, false, false);
}
}
public void Add(int key, bool occupied, bool completed)
{
var laneInfo = new LaneInfo();
laneinfo.Occupied = occupied;
laneinfo.Completed = completed;
this.laneInfoDict.Add(key, laneinfo);
}
public void Complete(int key)
{
laneInfoDict[key].Completed = true;
}
public void Occupy(int key)
{
laneInfoDict[key].Occupied = true;
}
public void Free(int key)
{
laneInfoDict[key].Occupied = false;
}
}
I suspect you might also need some way to read the info about your lanes too, add methods such as
public bool IsComplete(int key)
{
return laneInfoDict[key].Complete;
}
The answer to your question is that you should not use a Dictionary. Iterating a List<T>.Contains is faster than Dictionary<TKey, TValye> lookup for 7 items, especially if you are accessing them by index integer 0-6.
Part from that, Dictionary<TKey, TValue> is already generic and so there is no need to inherit from it. Sometimes you would wrap it, for various reasons (one might be locking). But if it is just for a few methods you can simply add extension methods to the Dictionary<int, LaneInfo>.
public static class LaneExtensionMethods
{
public static bool IsComplete(this Dictionary<int, LaneInfo> dictionary, int key)
{
return dictionary[key].Complete;
}
}
// Use
var d = new Dictionary<int, LaneInfo>();
var isComplete = d.IsComplete(1);
I often replace the int with a type to avoid bugs and confusion in code. This would in your case also allow for specialized extension methods. Casting has zero CPU cost (its just cosmetics in code).
public enum LaneId : Int32 { }
public static class LaneExtensionMethods
{
public static bool IsComplete(this Dictionary<LaneId, LaneInfo> dictionary, LaneId key)
{
return dictionary[key].Complete;
}
}
// Use
var d = new Dictionary<LaneId, LaneInfo>();
var laneId = (LaneId)1; // We cast from integer to LaneId, but use LaneId type everywhere in our app
var isComplete = d.IsComplete(laneId);
I was going over some code that a knowledgeable colleague wrote and I came across a technique I found confusing. Here is a snippet of code ...
public class TaxController : ApiController
{
private StateTaxApi taxApi = new taxApi();
[HttpGet]
public async Task<IEnumerable<String>> GetStatesOwedTax(String taxId, String clientId)
{
try
{
return await taxApi.GetStatesOwedTax(clientId, GetTaxId(), GetClientId());
}
catch (Exception e)
{
throw new ApiException(HttpStatusCode.BadRequest, "Could not get tax states", e);
}
}
private String GetClientId()
{
try
{
return Request.Headers.GetValues("client-id").FirstOrDefault();
}
catch (InvalidOperationException e)
{
// TODO: Handle error here
}
return null;
}
private String GetTaxId()
{
return GetSessionValue("taxId") as String;
}
private Object GetSessionValue(String key)
{
var context = Request.Properties["MS_HttpContext"] as HttpContextWrapper;
var session = context.Session;
return session[key];
}
}
Here you can see the methods are being passed as parameters to the method GetStatesOwedTax():
return await taxApi.GetStatesOwedTax(clientId, GetTaxId(), GetClientId());
I thought the only way to do this was to use a delegate to represent the method being passed in as a parameter. I see no mention of Func(string) defining the delegates. What am I missing?
The method isn't being passed, the result of the method is being passed. As simple as that is to say, I find an example always serves better.
public void Start()
{
var result = DoMath(GetX(), GetY());
}
public int GetX()
{
return 1;
}
public int GetY()
{
return 2;
}
public int DoMath(int x, int y)
{
return x + y;
}
As you can see in the example, DoMath() needs two ints passed into it. In lieu of
public void Start()
{
var x = GetX();
var y = GetY();
var result = DoMath(x, y);
}
you can do the method calls directly in the parameters of the DoMath() method.
Now, whether this is simpler, better, good/bad practice all comes down to personal style and overall complexity. If it's very readable then you can save space by doing this, but it does risk muddying up the waters and not being as apparent to what you're doing. So I can't say if you should or should not do it, just saying that you can do it.
As mentioned by Vilx in the comments, an easy way to tell if the method is being passed vs the results of the method are the inclusion of the parenthesis. If they are there (as they are in this case) then it means the method will be evaluated and its result used.
How do i get property name of the executing property. If the property uses "return" then
MethodBase.GetCurrentMethod().Name returns the name of the property. But when I use "yield return" MethodBase.GetCurrentMethod().Name returns "MoveNext". how do I get the executing property name when it uses yield return?
Sample Code
class Program
{
static void Main(string[] args)
{
var x = myProgram.Something;
Console.ReadLine();
}
}
public class myProgram
{
public static IEnumerable<string> Something
{
get
{
string var = MethodBase.GetCurrentMethod().Name;
for (int i = 0; i < 5; i++)
{
yield return var;
}
}
}
}
As you've probably noticed, the compiler reorganizes how the methods work and Something returns a private class that implements IEnumerable. As such, the actual contents of your method appear in the MoveNext method of this private class, so MethodBase.GetCurrentMethod doesn't return what it seems like it should return.
It happens that the name of the private class is derived from the original method name, which in this case is <Enumerate>d__0. So, you can parse the original method name from a stack frame.
static IEnumerable<string> Enumerate()
{
var method = new StackTrace(true).GetFrame(0).GetMethod().DeclaringType.Name;
yield return Regex.Replace(method, #".*<([^)]+)>.*", "$1");
}
static void Main(string[] args)
{
foreach (var #string in Enumerate())
{
Console.WriteLine(#string);
}
}
This is, of course, a hack and could easily not work in future versions of .NET
As you can probably guess, the problem here is that a yield return statement does a bit of rewriting behind the scenes, similar to how a using or lambda expression does. It actually gets implemented as an enumerator, with the code that calls yield return being part of the MoveNext method on the enumerator.
This is an overall problem of using Reflection: it gives you runtime information about your executing code, which may not match your compile-time idea of what that code was.
That's a long-winded way of saying that there's no easy way to get the information you want. If you were to move the yield return next into a separate method, then any code outside of that method would not be part of the MoveNext, but that may or may not accomplish what you need. You are no longer actually getting the name of the method that is executing the yield return, you are getting the name of it's caller. If that's all you care about, it looks like this:
public IEnumerable<string> Something
{
get
{
var x = MethodBase.GetCurrentMethod().Name;
return this.DoSomething(x);
}
}
private IEnumerable<string> DoSomething(string x)
{
for (int i = 0; i < 5; i++)
{
yield return x;
}
}
EDIT: While I doubt it will help you in the short term, for the record, this problem is also solved when using C# 5's new attributes. Since the CallerMemberName attribute is resolved at compile time, and apparently before the iterator has been rewritten into an enumerator class, it produces the name of the property:
public IEnumerable<string> Something
{
get
{
var x = this.GetCallerName();
for (int i = 0; i < 5; i++)
{
yield return x;
}
}
}
private string GetCallerName([CallerMemberName] string caller = null)
{
return caller;
}
I would move the iterator into a helper method:
public class myProgram
{
public static IEnumerable<string> Something
{
get
{
string var = MethodBase.GetCurrentMethod().Name;
return GetSomethingInternal();
}
}
private static IEnumerable<string> GetSomethingInternal()
{
for (int i = 0; i < 5; i++)
{
yield return i;
}
}
}
I would like to implement lazy loading on properties with PostSharp.
To make it short, instead of writing
SomeType _field = null;
private SomeType Field
{
get
{
if (_field == null)
{
_field = LongOperation();
}
return _field;
}
}
I would like to write
[LazyLoadAspect]
private object Field
{
get
{
return LongOperation();
}
}
So, I identify that I need to emit some code in the class to generate the backing field, as well as inside the getter method in order to implement the test.
With PostSharp, I was considering overriding CompileTimeInitialize, but I am missing the knowledge to get a handle over the compiled code.
EDIT:
The question can be extended to any parameterless method like:
SomeType _lazyLoadedField = null;
SomeType LazyLoadableMethod ()
{
if(_lazyLoadedField ==null)
{
// Long operations code...
_lazyLoadedField = someType;
}
return _lazyLoadedField ;
}
would become
[LazyLoad]
SomeType LazyLoadableMethod ()
{
// Long operations code...
return someType;
}
After our comments, I think I know what you want now.
[Serializable]
public class LazyLoadGetter : LocationInterceptionAspect, IInstanceScopedAspect
{
private object backing;
public override void OnGetValue(LocationInterceptionArgs args)
{
if (backing == null)
{
args.ProceedGetValue();
backing = args.Value;
}
args.Value = backing;
}
public object CreateInstance(AdviceArgs adviceArgs)
{
return this.MemberwiseClone();
}
public void RuntimeInitializeInstance()
{
}
}
Test code
public class test
{
[LazyLoadGetter]
public int MyProperty { get { return LongOperation(); } }
}
Thanks to DustinDavis's answer and comments, I could work on my own implementation, and I just wanted here to share it to help other people.
The main differences from the original answer are:
Implement the suggested "only run the operation once" (purpose of the lock)
Made the initialization status of the backing field more reliable by passing this responsibility to a boolean.
Here is the code:
[Serializable]
public class LazyLoadAttribute : LocationInterceptionAspect, IInstanceScopedAspect
{
// Concurrent accesses management
private readonly object _locker = new object();
// the backing field where the loaded value is stored the first time.
private object _backingField;
// More reliable than checking _backingField for null as the result of the loading could be null.
private bool _hasBeenLoaded = false;
public override void OnGetValue(LocationInterceptionArgs args)
{
if (_hasBeenLoaded)
{
// Job already done
args.Value = _backingField;
return;
}
lock (_locker)
{
// Once the lock passed, we must check if the aspect has been loaded meanwhile or not.
if (_hasBeenLoaded)
{
args.Value = _backingField;
return;
}
// First call to the getter => need to load it.
args.ProceedGetValue();
// Indicate that we Loaded it
_hasBeenLoaded = true;
// store the result.
_backingField = args.Value;
}
}
public object CreateInstance(AdviceArgs adviceArgs)
{
return MemberwiseClone();
}
public void RuntimeInitializeInstance() { }
}
I think the requirement cannot be accurately described as 'lazy loading', but is a special case of a more general caching aspect with in-AppDomain storage but without eviction. A general caching aspect would be able to handle method parameters.
I'm writing a wrapper around a 3rd party library, and it has a method to scan the data it manages. The method takes a callback method that it calls for each item in the data that it finds.
e.g. The method is essentially: void Scan(Action<object> callback);
I want to wrap it and expose a method like IEnumerable<object> Scan();
Is this possible without resorting to a separate thread to do the actual scan and a buffer?
You can do this quite simply with Reactive:
class Program
{
static void Main(string[] args)
{
foreach (var x in CallBackToEnumerable<int>(Scan))
Console.WriteLine(x);
}
static IEnumerable<T> CallBackToEnumerable<T>(Action<Action<T>> functionReceivingCallback)
{
return Observable.Create<T>(o =>
{
// Schedule this onto another thread, otherwise it will block:
Scheduler.Later.Schedule(() =>
{
functionReceivingCallback(o.OnNext);
o.OnCompleted();
});
return () => { };
}).ToEnumerable();
}
public static void Scan(Action<int> act)
{
for (int i = 0; i < 100; i++)
{
// Delay to prove this is working asynchronously.
Thread.Sleep(100);
act(i);
}
}
}
Remember that this doesn't take care of things like cancellation, since the callback method doesn't really allow it. A proper solution would require work on the part of the external library.
You should investigate the Rx project — this allows an event source to be consumed as an IEnumerable.
I'm not sure if it allows vanilla callbacks to be presented as such (it's aimed at .NET events) but it would be worth a look as it should be possible to present a regular callback as an IObservable.
Here is a blocking enumerator (the Scan method needs to run in a separate thread)
public class MyEnumerator : IEnumerator<object>
{
private readonly Queue<object> _queue = new Queue<object>();
private ManualResetEvent _event = new ManualResetEvent(false);
public void Callback(object value)
{
lock (_queue)
{
_queue.Enqueue(value);
_event.Set();
}
}
public void Dispose()
{
}
public bool MoveNext()
{
_event.WaitOne();
lock (_queue)
{
Current = _queue.Dequeue();
if (_queue.Count == 0)
_event.Reset();
}
return true;
}
public void Reset()
{
_queue.Clear();
}
public object Current { get; private set; }
object IEnumerator.Current
{
get { return Current; }
}
}
static void Main(string[] args)
{
var enumerator = new MyEnumerator();
Scan(enumerator.Callback);
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
You could wrap it in a simple IEnumerable<Object>, but I would not recommend it. IEnumerable lists implies that you can run multiple enumerators on the same list, which you can't in this case.
How about this one:
IEnumerable<Object> Scan()
{
List<Object> objList = new List<Object>();
Action<Object> action = (obj) => { objList.Add(obj); };
Scan(action);
return objList;
}
Take a look at the yield keyword -- which will allow you to have a method that looks like an IEnumerable but which actually does processing for each return value.