For performance reasons, I'm trying to reduce the overhead of having a new instance of a reference type created every time a particular method is called.
As a basic example:
public int AccumulativeCount(Expression<Func<int>> exp)
{
// usually do something useful with "exp". Instead put a
// breakpoint and get the memory reference of exp via "&exp"
return 1;
}
When it is called elsewhere in the code, the reference of exp in the AccumulativeCount method is different:
AccumulativeCount(() => 7);
Is there a way to make the parameter from the calling code static inline? In the example above the parameter "() => 7" is obviously never going to change, so there is no compelling reason why it should be recreated every time.
I'm aware that I could change the calling code to be:
public static Expression<Func<int>> MyStaticCountExp = () => 7;
// ... later in the code
AccumulativeCount(MyStaticCountExp);
The reason why I'm against the above is the expression only makes sense in the context that it is a parameter for. Also the code is not as clean as it could be. Is there something like:
AccumulativeCount(static () => 7); // does not compile
I don't know exactly your usecase, but maybe the Lazy<T> class will help.
public static readonly Lazy<int> Something = new Lazy<int>(() => AccumulativeCount(() => 7));
public static int AccumulativeCount(Expression<Func<int>> exp) {
// usually do something useful with "exp". Instead put a
// breakpoint and get the memory reference of exp via "&exp"
return 1;
}
public static void DoSomething() {
// the value was not available, so the AccumulativeCount(...) will be called
var a = Something.Value;
// the value is already created, no more call of AccumulativeCount(...) is needed
var b = Something.Value;
var c = Something.Value;
var d = Something.Value;
}
Related
I want to create a Lazy<> with runtime information about the contained type, but I'm not sure how to create the required Func<> initializer. I feel the answer is somewhere in Delegate.CreateDelegate, but I couldn't see how to make that work. The below illustrates what I want to do:
class ShapeTools {
abstract class Shape {}
class Square : Shape {}
Lazy<Square> aLazyShape;
ShapeTools() {
setup(GetType().GetFields().Where(f => f.Name == "aLazyShape").First());
}
// returns a shape matching the provided type (unimplemented)
Shape GetShape(Type shapeType) { return null; }
void setup (FieldInfo field) { // aLazyShape
var funcType = typeof(Func<>).MakeGenericType(field.FieldType); // = typeof(Func<Square>)
var shapeType = funcType.GetGenericArguments().First(); // = typeof(Square)
// var myFunc = Activator.CreateInstance(funcType, () => { return GetShape(shapeType); }) // doesn't compile - type doesn't match
var lazy = Activator.CreateInstance(field.FieldType, myFunc); // This takes a Func<Square>
field.SetValue(this, lazy);
}
}
You can achieve what you're looking for by using System.Linq.Expressions. Why you want to do it this way is another thing. =)
See this other answer for where the key parts about using Expression came from.
Note that your code for creating var funcType was not returning typeof(Func<Square>), but instead typeof(Func<Lazy<Square>>); I fixed that. Most things were made public for convenience when compiling. You could change the access to GetShape if you want to update BindingFlags in the call to GetMethod, for example.
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace SomeNamespace
{
class Program
{
static void Main(string[] args)
{
ShapeTools st = new ShapeTools();
ShapeTools.Square s = st.aLazyShape.Value;
// s will be whatever ShapeTools.GetShape returns
}
public class ShapeTools
{
public abstract class Shape { }
public class Square : Shape { }
public Lazy<Square> aLazyShape;
public ShapeTools()
{
setup(GetType().GetFields().Where(f => f.Name == "aLazyShape").First());
}
// returns a shape matching the provided type (unimplemented, just an example)
public static object GetShape(Type shapeType) { return new Square(); }
void setup(FieldInfo field)
{ // only handles 'aLazyShape' right now
Type funcType = typeof(Func<>).MakeGenericType(field.FieldType.GenericTypeArguments[0]); // = typeof(Func<Square>)
Type shapeType = funcType.GetGenericArguments().First(); // = typeof(Square)
// get MethodInfo for the static method in this class that returns the right shape
MethodInfo getInstanceOfType = GetType().GetMethod(nameof(GetShape));
// build the Func dynamically
var typeConst = Expression.Constant(shapeType); // get the shapeType as an Expression
var callGetInstance = Expression.Call(getInstanceOfType, typeConst); // invoke our (static) method to get the instance of shape
var cast = Expression.Convert(callGetInstance, shapeType); // cast the return of our method (which is object) to the right type
var toLambda = Expression.Lambda(cast); // wrap everything in a Lambda to return our instance
var finalFunc = toLambda.Compile(); // compile to the final Func
var lazy = Activator.CreateInstance(field.FieldType, finalFunc); // now create the Lazy<T>, where T is Square
field.SetValue(this, lazy);
}
}
}
}
Lastly, notice that GetShape was made static. This was for convenience when using Expressions - if you want, you can pass in an instance of ShapeTools to the Expressions code instead.
And as written, ShapeTools.setup is just an example of how this can work. I assume you'd want to clean it up to handle other field types than just Lazy<Shape>.
// var myFunc = Activator.CreateInstance(funcType, () => { return GetShape(shapeType); }) // doesn't compile - type doesn't match
C# is a statically typed language, and as such every type has to be fully known at compile time. As you discovered, while you can ask the runtime to create you any type you build the definition for (with a Type object), the return type has to be fully known -- the function you call returns object for that very reason.
You have a few options here:
Stay on the object level, and use further reflection calls to consume your newly created object. Large performance hit, of course.
Go dynamic, which creates a compiler site to translate any calls through it. It also spreads like a plague, anything that uses dynamic returns dynamic, so until you get something you know the type of you'll be using this kind of calls. Amortized moderate performance hit, very high performance hit during the first JIT compilation.
Use interfaces. You have a base class already, if you define it smart enough, that should be all you need to use your object. That myfunc function would be of type Func<Shape> in that case, and it obviously can only access the Shape portion of your object, though you're free to try casting using is/as as needed, usually in ifs. Very low performance hit, but you need to design your type smart (which you should be doing anyway).
I am attempting to implement a method like:
(Func<T> getFn, Action<T> setFn) MakePair<T>(T initialVal) {
}
It will return two runtime generated lambdas that get and set a dynamically created variable using Expression trees to create the code.
My current solution is to dynamically create an array of the type with one element, and reference that:
(Func<T> getFn, Action<T> setFn) MakePair<T>(T initialVal) {
var dynvar = Array.CreateInstance(typeof(T), 1);
Expression<Func<Array>> f = () => dynvar;
var dynref = Expression.Convert(f.Body, typeof(T).MakeArrayType());
var e0 = Expression.Constant(0);
var getBody = Expression.ArrayIndex(dynref, e0);
var setParam = Expression.Parameter(typeof(T));
var setBody = Expression.Assign(Expression.ArrayAccess(dynref, e0), setParam);
var getFn = Expression.Lambda<Func<T>>(getBody).Compile();
var setFn = Expression.Lambda<Action<T>>(setBody, setParam).Compile();
return (getFn, setFn);
}
Is there a better way to create what may be a value type variable at runtime that can be read/written to than using an array?
Is there a better way to reference the runtime created array other than using a lambda to create the (field?) reference for use in the ArrayIndex/ArrayAccess method calls?
Excessive Background Info
For those that wonder, ultimately this came up in an attempt to create something like Perl auto-virification of lvalues for Perl hashes.
Imagine you have a List<T> with duplicate elements and want to create a Dictionary<T,int> that allows you to look up the count for each unique T in the list. You can use a few lines of code to count (in this case T is int):
var countDict = new Dictionary<int, int>();
foreach (var n in testarray) {
countDict.TryGetValue(n, out int c);
countDict[n] = c + 1;
}
But I want to do this with LINQ, and I want to avoid double-indexing countDict (interestingly, ConcurrentDictionary has AddOrUpdate for this purpose) so I use Aggregate:
var countDict = testarray.Aggregate(new Dictionary<int,int>(), (d, n) => { ++d[n]; return d; });
But this has a couple of issues. First, Dictionary won't create a value for a missing value, so you need a new type of Dictionary that auto-creates missing values using e.g. a seed lambda:
var countDict = testarray.Aggregate(new SeedDictionary<int, Ref<int>>(() => Ref.Of(() => 0)), (d, n) => { var r = d[n]; ++r.Value; return d; });
But you still have the lvalue problem, so you replace the plain int counter with a Ref class. Unfortunately, C# can't create a C++ first class Ref class, but using one based around auto-creating a setter lambda from a getter lambda (using expression trees) is close enough. (Unfortunately C# still won't accept ++d[n].Value; even though it should be valid, so you have to create a temporary.)
But now you have the problem of creating multiple runtime integer variables to hold the counts. I extended the Ref<> class to take a lambda that returns a constant (ConstantExpression) and create a runtime variable and build a getter and setter with the constant being the initial value.
I agree with some of the question commenters that expression trees seem unnecessary, so here is a simple implementation of the shown API without them:
struct Box<T> {
public T Value;
}
(Func<T> getFn, Action<T> setFn) MakePair<T>(T initialVal) {
var box = new Box<T> { Value = initialVal };
return (() => box.Value, v => box.Value = v);
}
As an answer to the stated question (how to define dynref without a lambda), then, is there something wrong with the following modifications to dynvar and dynref?
var dynvar = new T[] { initialVal };
var dynref = Expression.Constant(dynvar);
When i get exception, it quite hard read error stack if I have lamda functions.
For example for this code:
public void Test()
{
Func<AnotherClass, bool> myLambda = (AnotherClass p) =>
{
if (p != null)
{
throw new Exception("Exception in method");
}
return true;
};
AnotherClass ac = new AnotherClass();
var r = myLambda(ac);
}
public class AnotherClass
{
}
I will get stack error like:
"CSharpTests.exe Error: 0 : System.Exception: Exception in method
at CSharpTests.MarketingEntityManager.<>c.<Test>b__0_0(AnotherClass p)
at CSharpTests.MarketingEntityManager.Test()
at CSharpTests.DisplayClassTest.Test()"
It was asked many times, what is <>c.b__0_0
But additionally interesting, may be why myLabda name I used in my code, was not used for generate name, and b__0_0 was generated.
and where is DisplayName text?
Your anonymous method isn't named myLambda. A delegate to the anonymous method is assigned to the myLambda local variable. In truth, your anonymous method has a "secret" name, given to it by the compiler, and it is <Test>b__0_0 (and it is then "hidden" in a nested class named <>c), but this name can change between compilations based on the number of other anonymous methods in the same class.
To give a (degenerate) example (that is very common in Javascript), this is legal:
((Func<AnotherClass, bool>)((AnotherClass p) =>
{
if (p != null)
{
throw new Exception("Exception in method");
}
return true;
}))(new AnotherClass());
Here we don't assign the delegate of the method to any variable, but we use it immediately to invoke the class. The number of brackets is terrible :-)
Another classical example:
var coll = new int[5];
var enu = coll.Select(x => x + 1).ToArray();
Here x => x + 1 is an anonymous method (of which a delegate is created by the .NET and passed to Enumerable.Select)... There is no name anywhere.
myLamda is just the name of the delegate that references your method. It´s not the name of that method. The latter is generated from the compiler, you can´t change it.
To clearify this a little imagine you didn´t have an anonymous method at all and would reference named method with your delegate:
myLambda = MyMethod;
Now it´s pretty clear that the stacktrace would contain MyMethod, not myLambda, wouldn´t it?
I want to moq a property that has an index, and I want to be able to use the index values in the callback, the same way you can use method arguments in the callback for moq'd methods. Probably easiest to demonstrate with an example:
public interface IToMoq
{
int Add(int x, int y);
int this[int x] { get; set; }
}
Action<int, int> DoSet = (int x, int y) =>
{
Console.WriteLine("setting this[{0}] = {1}", x, y);
throw new Exception("Do I ever get called?");
};
var mock = new Mock<IToMoq>(MockBehavior.Strict);
//This works perfectly
mock.Setup(m => m.Add(It.IsAny<int>(), It.IsAny<int>()))
.Returns<int, int>((a, b) => a + b);
//This compiles, but my callback never seems to be called
mock.SetupSet(m => m[It.IsAny<int>()] = It.IsAny<int>())
.Callback(DoSet);
var obj = mock.Object;
Console.WriteLine("Add(3,4) => {0}", obj.Add(3, 4)); //Works perfectly
obj[1] = 2; //Does not throw, why?
Edit: To clarify, I want the callback/returns method for the get to be Func<int,int>, and the callback/returns method for the set to be Action<int,int>. Trying what Mike suggested, you can sort of do this for set, but with one major limitation:
mock.SetupSet(m => m[23] = It.IsAny<int>())
.Callback(DoSet).Verifiable();
The callback DoSet is indeed then called with values (23,<any>). Unfortunately, using It.IsAny<int>() instead of 23 seems to behave as 0, rather than <any>.
Also, I couldn't find a way of calling SetupGet with Returns where Returns takes a Func<int,int> that would even compile.
Is it possible to use Moq for this?
Motivation: I'm just playing with Moq, attempting to use it to provide a fluent API for performing interception. That is, given an interface I and an instance X of I, automatically create a Mock<I> proxy with behaviour defaulting to X.
Would probably make more sense to work directly with Castle DP, but I like the Moq Expression Tree syntax.
The method SetupSet takes a plain delegate, not an expression tree of type Expression<...> like many other Moq methods.
For that reason Moq cannot see that you used It.IsAny. Instead, It.IsAny is called (not what we want) and Moq sees its return value only which happens to be default(int), or 0.
As of Moq 4.2.1502.0911 for .NET Framework 4.5, I found the following behavior to be true.
The problem you're running into is specifically due to the It.IsAny<T> call. If you use It.IsAny<T>, the callback does not execute:
[Test]
public void DoesNotExecuteCallback()
{
// Arrange
var mock = new Mock<IIndexable>();
var called = false;
mock.SetupSet(m => m[It.IsAny<int>()] = It.IsAny<int>()).Callback<int,int>((x, y) => called = true);
var instance = mock.Object;
// Act
instance[1] = 2;
// Arrange
Assert.That(called, Is.False);
}
But if you call it using specific parameters, it calls the callback:
[Test]
public void DoesExecuteCallback()
{
// Arrange
var mock = new Mock<IIndexable>();
var called = false;
mock.SetupSet(m => m[1] = 2).Callback<int,int>((x, y) => called = true);
var instance = mock.Object;
// Act
instance[1] = 2;
// Arrange
Assert.That(called, Is.True);
}
To summarize, you should avoid the use of the It.IsAny when trying to setup expectations for an indexer. In general, you should be avoiding the use of it because it can encourage sloppy test writing
There are appropriate use cases for It.IsAny, but without knowing the specifics I tend to recommend against it.
I've a method on a generic base class that I want to execute for all superclasses of it
The logic is something like:
BuildAverageDateStats(List<type> items, DateProperty1 exp, DateProperty2 exp2)
{
return new Stat{
Value = items.Average(c => (c.DateProperty2 - c.DateProperty1).Milliseconds)
};
}
myobject.BuildAverageDateStats(list, () => c.QueuedDate, () => c.CompletedDate);
myobject.BuildAverageDateStats(list, () => c.ActionedDate, () => c.CompletedDate);
I think I need expressions, but not sure how...
I could send it in as Func i.e. Value = items.Average(c => myfunc(c)) but looking for a property substitution example.
Stat BuildAverageDateStats<U>(List<type> items, Func<U, double> exp)
where U:type
{
return new Stat{
Value = items.OfType<U>().Average(exp);
};
}
You can call it like this
BuidlAverageDateStats<Dog>(items, d=>d.Age - d.Height);
Though my example doesn't make sense.
If you are really only ever going to use one of the three DateTime properties that you have right now, I would keep the method signature the way you have it right now.
To make things neater, make some public static readonly delegate fields on your class for your properties, and use those, instead of writing the same expression time and time again:
public static readonly DateSelector Date1Property = delegate(CompareTest c) { return c.Date1; };
public static readonly DateSelector Date2Property = delegate(CompareTest c) { return c.Date2; };
public static readonly DateSelector Date3Property = delegate(CompareTest c) { return c.Date3; };
If, on the other hand, you expect inheriting classes to implement more properties than the three you have right now, you could consider passing in the properties as String and using the Dynamic Linq Library (and build a dynamic expression that returns the property) or a DynamicMethod to return your property. Both would have the benefits of reflection with the painful performance. If you need it, I have some code laying around for that.
Type safety will be out the window though, so I wouldn't use it unless necessary, and it sounds like it isn't.
Menno
static Stat BuildAverageDateStats<T>(List<T> items, string pname1, string pname2){
return new Stat {
Value = items.Average( c =>
{
var ty = c.GetType();
var pv1 = (dynamic)ty.GetProperty(pname1).GetValue(c,null);
var pv2 = (dynamic)ty.GetProperty(pname2).GetValue(c,null);
return pv2 - pv1;
})
};
}