This question already has answers here:
Possible pitfalls of using this (extension method based) shorthand
(11 answers)
Closed 9 years ago.
How can I check for nulls in a deep lamda expression?
Say for example I have a class structure that was nested several layers deep, and I wanted to execute the following lambda:
x => x.Two.Three.Four.Foo
I want it to return null if Two, Three, or Four were null, rather than throwing a System.NullReferenceException.
public class Tests
{
// This test will succeed
[Fact]
public void ReturnsValueWhenClass2NotNull()
{
var one = new One();
one.Two = new Two();
one.Two.Three = new Three();
one.Two.Three.Four = new Four();
one.Two.Three.Four.Foo = "blah";
var result = GetValue(one, x => x.Two.Three.Four.Foo);
Assert.Equal("blah", result);
}
// This test will fail
[Fact]
public void ReturnsNullWhenClass2IsNull()
{
var one = new One();
var result = GetValue(one, x => x.Two.Three.Four.Foo);
Assert.Equal(null, result);
}
private TResult GetValue<TModel, TResult>(TModel model, Expression<Func<TModel, TResult>> expression)
{
var func = expression.Compile();
var value = func(model);
return value;
}
public class One
{
public Two Two { get; set; }
}
public class Two
{
public Three Three { get; set; }
}
public class Three
{
public Four Four { get; set; }
}
public class Four
{
public string Foo { get; set; }
public string Bar { get; set; }
}
}
UPDATE:
One solution would be to catch the NullReferenceException like this:
private TResult GetValue<TModel, TResult>(TModel model, Expression<Func<TModel, TResult>> expression)
{
TResult value;
try
{
var func = expression.Compile();
value = func(model);
}
catch (NullReferenceException)
{
value = default(TResult);
}
return value;
}
But I hate to incur the expense of catching an exception that is not, in my mind, exceptional. I expect this to be the case quite often in my domain.
UPDATE 2:
Another solution would be modify the property getters like this:
public class One
{
private Two two;
public Two Two
{
get
{
return two ?? new Two();
}
set
{
two = value;
}
}
}
Which is mostly ok for my domain, but there are times when I really to expect a property to return null. I checked the answer from Josh E as helpful since it comes pretty close to what I need in some cases.
You could do this with a generic helper extension method, something like:
public static class Get {
public static T IfNotNull<T, U>(this U item, Func<U, T> lambda) where U: class {
if (item == null) {
return default(T);
}
return lambda(item);
}
}
var one = new One();
string fooIfNotNull = one.IfNotNull(x => x.Two).IfNotNull(x => x.Three).IfNotNull(x => x.Four).IfNotNull(x => x.Foo);
You can't do that in a concise way. You can either make the lambda multiple lines, or use nested ternary operators:
var result = GetValue(one, x => x.Two == null ? null :
x.Two.Three == null ? null :
x.Two.Three.Four == null ? null :
x.Two.Three.Four.Foo;
Ugly, I know.
Doing this concisely requires an as-yet-unimplemented operator. We considered adding an operator ".?" to C# 4.0 which would have your desired semantics, but unfortunately it did not fit into our budget. We'll consider it for a hypothetical future version of the language.
You can now do using the Maybe project on codeplex.
Syntax is:
string result = One.Maybe(o => o.Two.Three.Four.Foo);
string cityName = Employee.Maybe(e => e.Person.Address.CityName);
I've written an extension method which enables you to do this:
blah.GetValueOrDefault(x => x.Two.Three.Four.Foo);
It uses Expression Trees to build a nested conditional checking for nulls at each node before returning the expression value; the created expression tree is compiled to a Func and cached, so subsequent uses of the same call should run at almost native speed.
You can also pass in a default value to return if you like:
blah.GetValueOrDefault(x => x.Two.Three.Four.Foo, Foo.Empty);
I've written a blog about it here.
I'm not skilled in c#, but maybe there's some way to implement the "andand" pattern from ruby that solves exactly this problem without polluting the implementation.
The concept is also known as the Maybe Monad in Haskell.
The title of this article seems promising.
Always initialize your properties before using them. Add a constructor to class One, Two, Three and Four. In the constructor initialize your properties so they are not null.
You could modify your getters to read something like:
private Two _two;
public Two Two
{
get
{
if (null == _two)
return new Two();
else
return _two;
}
}
I find the coalesce operator useful for this at times. This only helps though if there is a default/null equivalent version of the object you can drop in.
For instance, sometimes when I'm cracking open XML...
IEnumeratable<XElement> sample;
sample.Where(S => (S.Attribute["name"] ?? new XAttribute("name","")).Value.StartsWith("Hello"))...
Depending on how the default objects are retrieved this can be verbose, and the above example is not a great use but you get the idea. For the particular case of reading XML attributes I have an extension method that returns the attribute value or an empty string.
I converted a function that used a lot of if statements to avoid the nulls to the .IFNotNull method for classes that I converted from an XSD that are 4 and 5 levels deep.
Here are a few lines of the converted code:
ProdYear.PRIOR_CUMULATIVE_CARBON_DIOXIDE_VALUE = year.IfNotNull(x => x.PRIOR_CUMULATIVE).IfNotNull(y => y.CARBON_DIOXIDE).IfNotNull(z => z.VALUE).ToDouble();
ProdYear.PRIOR_CUMULATIVE_CARBON_DIOXIDE_UOM = year.IfNotNull(x => x.PRIOR_CUMULATIVE).IfNotNull(y => y.CARBON_DIOXIDE).IfNotNull(z => z.UOM);
Here are some interesting stats about it:
1) This new method took 3.7409 times longer to run that the variation with the If Statements.
2) I decreased my function line count from 157 to 59.
3) CodeRush from DevExpress has a "Maintenance Complexity" score. When I converted to the Lambda statements, it increased from 984 to 2076, which is theoretically much harder to maintain.
Related
This seems simple, but I can't decipher the LINQ required to do it. I also can't add any new dependencies.
Basically, I'm trying to make this code generic:
if (filter.matchMode.ToUpper().Equals("EQ")) {
query = query.Where(x => x.SomeField.Equals(filter.Value));
if (filter.matchMode.ToUpper().Equals("LT")) {
query = query.Where(x => x.SomeField < filter.Value);
} else [... 5 other match modes ...]
}
Now, SomeField is only one of about 5 fields that needs this functionality. And there's 5 matching operators. I could just copy/pasta the whole thing, and then deal with the debt of having to change tons of code every time a new operator or field enters the mix, but that really doesn't seem right.
Basically, I need some way of defining SomeField at runtime, so I can factor out the whole if/else tree and use it for each supported field.
I've tried going down this road, but I think I'm misunderstanding something fundamental about expressions:
var entityType = typeof(TableObject);
ParameterExpression arg = Expression.Parameter(entityType, "x");
MemberExpression amproperty = Expression.Property(arg, "SomeField");
MemberExpression property = Expression.Property(amproperty, "Equals"); // ???
// what's next, if this is even the right direction...
EDIT: a shorter version of the question might be: how can I construct the following object foo using MemberExpressions and lambdas, such that SomeField can be passed in as a string "SomeField":
Expression<Func<TableObject, bool>> foo = x => x.SomeField.Equals("FOO");
UPDATE: here's what I ended up coming up with:
private IQueryable<TableObject> processFilter(
IQueryable<TableObject> query,
FilterItem filter,
string fieldName)
{
var entityType = typeof(TableObject);
// construct the argument and access object
var propertyInfo = entityType.GetProperty(fieldName);
ParameterExpression arg = Expression.Parameter(entityType, "x");
MemberExpression access = Expression.MakeMemberAccess(arg,
typeof(TableObject).GetProperty(fieldName)
);
// translate the operation into the appropriate Expression method
Expression oprFunc;
if (filter.MatchMode.ToUpper().Equals("EQ")) {
oprfunc =
Expression.Equal(access, Expression.Constant(filter.Value));
} else if (filter.MatchMode.ToUpper().Equals("LT")) {
oprfunc =
Expression.LessThan(access, Expression.Constant(filter.IntValue));
} else {
throw new ArgumentException(
$"invalid argument: ${filter.MatchMode}"
);
}
// construct the lambda
var func = Expression.Lambda<Func<TableObject, bool>>(oprFunc, arg);
// return the new query
return query.Where(func);
}
So far, this seems to cover most of the cases. It starts to go off the rails with nullable fields and date comparisons, but it will work for what I need it to do. The part I'm still not completely sure about is Expression.MakeMemberAccess. I've seen this written many ways and I'm not sure if that's the correct way to create that expression.
Let's say you have class like this:
class SomeClass
{
public string a1 { get; set; }
public string b1 { get; set; }
public string c1 { get; set; }
}
also let's assume you have method like this:
public List<T> GetAll(Expression<Func<T, bool>> criteria )
{
return someDataLINQCapable.Where(criteria);
}
Method could be called like this:
GetAll<SomeClass>(m => m.a1 != null && m.b1=="SomethingUseful")
I need to create a general routine in visual studio to get some parameters as input and return a list resulted from a repository. I am using Linq. But I am not sure how to develop this function and neither what key words I can use and find some resources.
This is a sample code that already is used in my program:
var lstReceiptDetails = Repository<TransactionDetail>()
.Where(current => current.HeaderId == headerId)
.OrderBy(current => current.DocumentRow)
.ToList();
I need to change the above linq statement to something like the following pseudocode:
private List<> GetQuery(repositoryName, conditionFieldName, orderFieldName )
{
var lstResult = Repository<repositiryName>()
.Where(current => current.ConditionFieldName == conditionFieldName)
.OrderBy(current => current.orderFieldName)
.ToList();
Return(lstResult);
}
Any help is appreciate.
Maryam
I think the closest way you can get is by using the following example below. I've tried a several ways to do this, but it would harm the usability and the readability. This is a compromise between code duplication and readability.
A sample POCO object:
class TransactionDetail
{
public DateTime DateProcessed { get; set; }
public string AccountName { get; set; }
}
The repositories:
abstract class GenericRepository<T>
{
public List<T> GetQuery<TKey>(
Func<T, bool> conditionFieldName,
Func<T, TKey> orderFieldName)
{
var lstResult = Repository()
.Where(conditionFieldName)
.OrderBy(orderFieldName)
.ToList();
return lstResult;
}
private IEnumerable<T> Repository()
{
throw new NotImplementedException();
}
}
class TransactionDetailRepository : GenericRepository<TransactionDetail>
{
}
And caller-side:
var repository = new TransactionDetailRepository();
var transactions = repository.GetQuery(
x => x.AccountName == "Foo Bar",
x => x.DateProcessed);
Argument checks should still be implemented properly though.
If this piece of code should be used in EntityFramework or Linq-to-SQL, parameters should be wrapped in Expression<T> such that, for example: Func<T, bool> becomes Expression<Func<T, bool>>
You can try to use the LINQ Dynamic Query Library that take string arguments instead of type-safe language operators.
Short example:
var result = Repository<repositoryName>().
Where("Id = 1").
Select("new(Id, Name)");
More information here: http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library
I want to assert that the elements of two list contains values that I expected, something like:
var foundCollection = fooManager.LoadFoo();
var expectedCollection = new List<Foo>()
{
new Foo() { Bar = "a", Bar2 = "b" },
new Foo() { Bar = "c", Bar2 = "d" }
};
//assert: I use AreEquivalent since the order does not matter
CollectionAssert.AreEquivalent(expectedCollection, foundCollection);
However the above code will not work (I guess because .Equals() does not return true for different objects with the same value). In my test, I only care about the public property values, not whether the objects are equal. What can I do to make my assertion?
REWORKED ANSWER
There is a CollectionAssert.AreEqual(IEnumerable, IEnumerable, IComparer) overload to assert that two collections contain the same objects in the same order, using an IComparer implementation to check the object equivalence.
In the scenario described above, the order is not important. However, to sufficiently handle also the situation where there are multiple equivalent objects in the two collections, it becomes necessary to first order the objects in each collection and use one-by-one comparison to ensure that also the number of equivalent objects are the same in the two collections.
Enumerable.OrderBy provides an overload that takes an IComparer<T> argument. To ensure that the two collections are sorted in the same order, it is more or less required that the types of the identifying properties implement IComparable. Here is an example of a comparer class that implements both the IComparer and IComparer<Foo> interfaces, and where it is assumed that Bar takes precedence when ordering:
public class FooComparer : IComparer, IComparer<Foo>
{
public int Compare(object x, object y)
{
var lhs = x as Foo;
var rhs = y as Foo;
if (lhs == null || rhs == null) throw new InvalidOperationException();
return Compare(lhs, rhs);
}
public int Compare(Foo x, Foo y)
{
int temp;
return (temp = x.Bar.CompareTo(y.Bar)) != 0 ? temp : x.Bar2.CompareTo(y.Bar2);
}
}
To assert that the objects in the two collections are the same and comes in equal numbers (but not necessarily in the same order to begin with), the following lines should do the trick:
var comparer = new FooComparer();
CollectionAssert.AreEqual(
expectedCollection.OrderBy(foo => foo, comparer),
foundCollection.OrderBy(foo => foo, comparer), comparer);
No, NUnit has no such mechanism as of current state. You'll have to roll your own assertion logic. Either as separate method, or utilizing Has.All.Matches:
Assert.That(found, Has.All.Matches<Foo>(f => IsInExpected(f, expected)));
private bool IsInExpected(Foo item, IEnumerable<Foo> expected)
{
var matchedItem = expected.FirstOrDefault(f =>
f.Bar1 == item.Bar1 &&
f.Bar2 == item.Bar2 &&
f.Bar3 == item.Bar3
);
return matchedItem != null;
}
This of course assumes you know all relevant properties upfront (otherwise, IsInExpected will have to resort to reflection) and that element order is not relevant.
(And your assumption was correct, NUnit's collection asserts use default comparers for types, which in most cases of user defined ones will be object's ReferenceEquals)
Using Has.All.Matches() works very well for comparing a found collection to the expected collection. However, it is not necessary to define the predicate used by Has.All.Matches() as a separate function. For relatively simple comparisons, the predicate can be included as part of the lambda expression like this.
Assert.That(found, Has.All.Matches<Foo>(f =>
expected.Any(e =>
f.Bar1 == e.Bar1 &&
f.Bar2 == e.Bar2 &&
f.Bar3 == e.Bar3)));
Now, while this assertion will ensure that every entry in the found collection also exists in the expected collection, it does not prove the reverse, namely that every entry in the expected collection is contained in the found collection. So, when it is important to know that found and expected contain are semantically equivalent (i.e., they contain the same semantically equivalent entries), we must add an additional assertion.
The simplest choice is to add the following.
Assert.AreEqual(found.Count(), expected.Count());
For those who prefer a bigger hammer, the following assertion could be used instead.
Assert.That(expected, Has.All.Matches<Foo>(e =>
found.Any(f =>
e.Bar1 == f.Bar1 &&
e.Bar2 == f.Bar2 &&
e.Bar3 == f.Bar3)));
By using the first assertion above in conjunction with either the second (preferred) or third assertion, we have now proven that the two collections are semantically the same.
Have you tried something like this?
Assert.That(expectedCollection, Is.EquivalentTo(foundCollection))
I had a similar problem. Listing contributors, which contains "commenters" and other ppl... I want to get all the comments and from that derive the creators, but I'm ofc only interested in unique creators. If someone created 50 comments I only want her name to appear once. So I write a test to see that the commenters are int the GetContributors() result.
I may be wrong, but what I think your after (what I was after when I found this post) is to assert that there are exactly one of each item in one collection, found in another collection.
I solved this like so:
Assert.IsTrue(commenters.All(c => actual.Count(p => p.Id == c.Id) == 1));
If you also want the resulting list not to contain other items than expected you could just compare the length of the lists as well..
Assert.IsTrue(commenters.length == actual.Count());
I hope this is helpful, if so, I'd be very grateful if you would rate my answer.
To perform equivilance operations on complex types you need to implement IComaprable.
http://support.microsoft.com/kb/320727
Alternatively you could use recursive reflection, which is less desirable.
One option is to write custom constraints to compare the items. Here's a nice article on the subject: http://www.davidarno.org/2012/07/25/improving-nunit-custom-constraints-with-syntax-helpers/
I recommend against using reflection or anything complex, it just adds more work/maintenace.
Serialize the object (i recommend json) and string compare them.
I'm unsure why you object to order by but I'd still recommend it as it will save a custom compare's for each type.
And it automatically works with domain objects change.
Example (SharpTestsEx for fluent)
using Newtonsoft.Json;
using SharpTestsEx;
JsonConvert.SerializeObject(actual).Should().Be.EqualTo(JsonConvert.SerializeObject(expected));
You can write it as a simple extensions and make it more readable.
public static class CollectionAssertExtensions
{
public static void CollectionAreEqual<T>(this IEnumerable<T> actual, IEnumerable<T> expected)
{
JsonConvert.SerializeObject(actual).Should().Be.EqualTo(JsonConvert.SerializeObject(expected));
}
}
and then using your example call it like so:
var foundCollection = fooManager.LoadFoo();
var expectedCollection = new List<Foo>()
{
new Foo() { Bar = "a", Bar2 = "b" },
new Foo() { Bar = "c", Bar2 = "d" }
};
foundCollection.CollectionAreEqual(foundCollection);
You'll get an assert message like so:
...:"a","Bar2":"b"},{"Bar":"d","Bar2":"d"}]
...:"a","Bar2":"b"},{"Bar":"c","Bar2":"d"}]
...__________________^_____
Simple code explaining how to use the IComparer
using System.Collections;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace CollectionAssert
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
IComparer collectionComparer = new CollectionComparer();
var expected = new List<SomeModel>{ new SomeModel { Name = "SomeOne", Age = 40}, new SomeModel{Name="SomeOther", Age = 50}};
var actual = new List<SomeModel> { new SomeModel { Name = "SomeOne", Age = 40 }, new SomeModel { Name = "SomeOther", Age = 50 } };
NUnit.Framework.CollectionAssert.AreEqual(expected, actual, collectionComparer);
}
}
public class SomeModel
{
public string Name { get; set; }
public int Age { get; set; }
}
public class CollectionComparer : IComparer, IComparer<SomeModel>
{
public int Compare(SomeModel x, SomeModel y)
{
if(x == null || y == null) return -1;
return x.Age == y.Age && x.Name == y.Name ? 0 : -1;
}
public int Compare(object x, object y)
{
var modelX = x as SomeModel;
var modelY = y as SomeModel;
return Compare(modelX, modelY);
}
}
}
This solved my problem using NUnit's Assertion class from the NUnitCore assembly:
AssertArrayEqualsByElements(list1.ToArray(), list2.ToArray());
i went over some questions and searched google a bit,
but i couldnt find an answer ( That satisfies me ).
Basicly, i understand the SingleOrDefault return null or 0 ( depends on the type ).
but how can i make it return something else ?
return myChannels.All.Where(_Channel => _Channel.Guid == this.ParentChannelGuid).SingleOrDefault(_SPECIFICCHANNEL);
so, i want _SPECIFICCHANNEL to be returned in case it is not single..
can that be done ?
You will have to make an extension method:
public static T SingleOr<T>(this IEnumerable<T> list, T defaultValue) where T : class
{
return list.SingleOrDefault() ?? defaultValue;
}
There is no other way. All classes default to null.
This can be accomplished in a rather simple way. If you create your own extension method that is more specific than the generic SingleOrDefault, then the compiler will prefer the more type-specific version. Here's an example that shows how to do that with a simple Person class (you can copy-paste it into LINQPad to quickly see the result):
public class Person
{
public string Name { get; set; }
public override string ToString()
{
return Name ?? "";
}
}
public static class PersonExtensionMethod
{
public static Person SingleOrDefault(this IEnumerable<Person> source)
{
var person = Enumerable.SingleOrDefault(source);
if (person == null)
return new Person { Name = "Unnamed" };
return person;
}
}
public static void Main()
{
var emptyCollection = new Person[0];
var nonEmptyCollection = new Person[] { new Person { Name = "Jack" } };
Debug.WriteLine("Empty collection: " + emptyCollection.SingleOrDefault());
Debug.WriteLine("Non-empty collection: " + nonEmptyCollection.SingleOrDefault());
}
In the above example, SingleOrDefault(IEnumerable<Person>), takes precedence over SingleOrDefault<T>(IEnumerable<T>) which is less specific.
Could you use DefaultIfEmpty() (psedo code follows) -
return myChannels.All.Where(_Channel => _Channel.Guid == this.ParentChannelGuid).DefaultIfEmpty(_SPECIFICCHANNEL).SingleOrDefault();
but how can i make it return something else ?
You cannot. You can make your own method — as shown by Oskar Kjellin — to return someting else, but SingleOrDefault will always behave as programmed, which means return the default value (null, 0) for an item.
Why not just use the "??" operator and say
return myChannels.SingleOrDefault(_Channel => _Channel.Guid == this.ParentChannelGuid) ??_SPECIFICCHANNEL;
You cannot define the default value of a type. It is always defined as null for reference types. For structs, it is an instance of the struct where all member fields in turn are set to their default values. For enums, it is always 0 (which may or may not be a defined value of the enum type in question)
Expanding on Oskar's answer of an extension method you can make that more generic so that it covers value as well as reference types with something like the below:
public static T SingleOrSpecifiedDefault<T>(this IEnumerable<T> enumerable, Expression<Func<T, bool>> singleOrDefault, T defaultValue) where T : IComparable
{
T singleValue = enumerable.SingleOrDefault(singleOrDefault.Compile());
if (singleValue == null || singleValue.CompareTo(default(T)) == 0)
{
return defaultValue;
}
return singleValue;
}
This allows you to specify the same LINQ expression that you'd use with SingleOrDefault as well as the defaultValue (which will be used if no match is found).
I am trying to use Lambda Expressions in a project to map to a third party query API. So, I'm parsing the Expression tree by hand.
If I pass in a lambda expression like:
p => p.Title == "title"
everything works.
However, if my lambda expression looks like:
p => p.Title == myaspdropdown.SelectedValue
Using the .NET debugger, I don't see the actual value of that funciton. Instead I see something like:
p => p.Title = (value(ASP.usercontrols_myaspusercontrol_ascx).myaspdropdown.SelectedValue)
What gives? And when I try to grab the right side of the expression as a string, I get (value(ASP.usercontrols_myaspusercontrol_ascx).myaspdropdown.SelectedValue) instead of the actual value. How do I get the actual value?
Remember that when you're dealing with the lambda expression as an expression tree, you don't have executable code. Rather you have a tree of expression elements, that make up the expression you wrote.
Charlie Calvert has a good post that discusses this in detail. Included is an example of using an expression visualiser for debugging expressions.
In your case, to get the value of the righthand side of the equality expression, you'll need to create a new lambda expression, compile it and then invoke it.
I've hacked together a quick example of this - hope it delivers what you need.
public class Class1
{
public string Selection { get; set; }
public void Sample()
{
Selection = "Example";
Example<Book, bool>(p => p.Title == Selection);
}
public void Example<T,TResult>(Expression<Func<T,TResult>> exp)
{
BinaryExpression equality = (BinaryExpression)exp.Body;
Debug.Assert(equality.NodeType == ExpressionType.Equal);
// Note that you need to know the type of the rhs of the equality
var accessorExpression = Expression.Lambda<Func<string>>(equality.Right);
Func<string> accessor = accessorExpression.Compile();
var value = accessor();
Debug.Assert(value == Selection);
}
}
public class Book
{
public string Title { get; set; }
}
To get the actual value, you need to apply the logic of the expression tree to whatever context you've got.
The whole point of expression trees is that they represent the logic as data rather than evaluating the expression. You'll need to work out what the lambda expression truly means. That may mean evaluating some parts of it against local data - you'll need to decide that for yourself. Expression trees are very powerful, but it's not a simple matter to parse and use them. (Ask anyone who's written a LINQ provider... Frans Bouma has bemoaned the difficulties several times.)
Just been struggling with exactly the same issue, thanks Bevan. On an extension, the following is a generic pattern you can use to extract the value (using this in my query engine).
[TestFixture]
public class TestClass
{
[Test]
public void TEst()
{
var user = new User {Id = 123};
var idToSearch = user.Id;
var query = Creator.CreateQuery<User>()
.Where(x => x.Id == idToSearch);
}
}
public class Query<T>
{
public Query<T> Where(Expression<Func<T, object>> filter)
{
var rightValue = GenericHelper.GetVariableValue(((BinaryExpression)((UnaryExpression)filter.Body).Operand).Right.Type, ((BinaryExpression)((UnaryExpression)filter.Body).Operand).Right);
Console.WriteLine(rightValue);
return this;
}
}
internal class GenericHelper
{
internal static object GetVariableValue(Type variableType, Expression expression)
{
var targetMethodInfo = typeof(InvokeGeneric).GetMethod("GetVariableValue");
var genericTargetCall = targetMethodInfo.MakeGenericMethod(variableType);
return genericTargetCall.Invoke(new InvokeGeneric(), new[] { expression });
}
}
internal class InvokeGeneric
{
public T GetVariableValue<T>(Expression expression) where T : class
{
var accessorExpression = Expression.Lambda<Func<T>>(expression);
var accessor = accessorExpression.Compile();
return accessor();
}
}
I'm not sure I understand. Where are you "seeing" that? Is that at design-time or run-time? Lambda expressions can be thought of essentially as anonymous delegates, and will operate with deferred execution. So you shouldn't expect to see the value assigned until after execution has passed that line, obviously.
I don't think that's really what you mean though... if you clarify the question a bit maybe I can help :)