pass properties as reference using Expressions - c#

This post details workarounds for passing properties as references including using Expressions such as
public void StoreProperty(Expression<Func<T, object>> expr)
This approach is ok and I note many frameworks appear to use this (eg automapper, autofac) as detailed in James Gregory's Introduction to static reflection where he states
The great thing about this is that if you change the name of a member inside a lambda, you’ll get a compile error if you haven’t updated all the references! No more hidden bugs.
Whilst I much prefer this approach it is still not perfect as you can pass any expression returning an object (or whatever your return val is) eg
x => x.Name) //fine
x => x.Name+"x") //runtime error
Is there currently any better way to reference the property (by locking down the Expression, or some other way)
If No, how might a future version of C# lock down the Expression? for example, something like:
public void StoreProperty(Expression<Func<T, object>> expr) where expr.Member is PropertyInfo
clarification: above is only an example, I know this isn't currently supported; thats what I'm trying to discuss.

Well, i don't see how it would be possible.
I wouldn't say it's "outrageous" to suggest, it's simply not the intended use.
In fact this whole concept, while very useful in this situation, was not designed to answer this case. LINQ was intended as an extendable query language with a rich expression mechanism.
Linq extends the language syntax to allow strong, type-safe expressions on the provided types and this is why you can use it in this way to get a strong and typesafe expression.
In this case, you are creating a function that transforms one data type (the T object) into another - a general object.
If i was prohibited from writing something like p=>p.Name+"something" i would lose a lot of the inherent flexibility of the language.
I.e. This would not be possible p=>p.X + p.Y as some query result that returns a sum of elements.
The solution you showed is designed to utilize a feature of linq - strong, type safe property names. It provides an elegant way of using linq to solve a problem, but like any solution - it is open to possible abuse.
A developer that passes p=>p.Name+"something" did not grok the intended use of the solution, which is a matter for training.

Related

Resharper search pattern to detect methods that return a value that is not used

I would like a resharper pattern to detect unhandled IDisposables if possible. If I have a method
IDisposable Subscribe(...){....}
and call it without assigning and using that IDisposable I would like to be told about it. I have tried the following pattern
;$expr$;
where expr is of type IDisposable. The following happens.
the first is detected correctly but the second is an error because simple assignment to an existing variable is also and expression in C# whereas assignment using var is not. Is it possible to detect that the return value is assigned via structural search?
I notice that resharper has the following code quality options
but I'm guessing they are built with something more sophisticated than the structural search parser.
Unfortunately, this can't be done with structural search and replace. For one thing, there is no construct to match against the absence of something, so there's no way to match against a method invocation that does NOT have an assignment of its return value.
As you note, there are inspections that track pure functions that don't use the return value, and they're not implemented with SSR. You can make them apply to your methods by applying the [Pure] attribute to them. However, this is implying that the method actually is pure, i.e. has no side effects, so may be the wrong semantic in this instance.

Does C# support type inference of the return type?

This is just a curiousity about if there is a fundamental thing stopping something like this (or correct me if there's already some way):
public TTo Convert<TTo, TFrom>(TFrom from)
{
...
}
Called like this:
SomeType someType = converter.Convert(someOtherType);
Because what would happen if you did this?
static void M(int x){}
static void M(double x){}
static T N<T>() {}
...
M(N());
Now what is T? int or double?
It's all very easy to solve the problem when you know what the type you're assigning to is, but much of the time the type you're assigning to is the thing you're trying to figure out in the first place.
Reasoning from inside to outside is hard enough. Reasoning from outside to inside is far more difficult, and doing both at the same time is extremely difficult. If it is hard for the compiler to understand what is going on, imagine how hard it is for the human trying to read, understand and debug the code when inferences can be made both from and to the type of the context of an expression. This kind of inference makes programs harder to understand, not easier, and so it would be a bad idea to add it to C#.
Now, that said, C# does support this feature with lambda expressions. When faced with an overload resolution problem in which the lambda can be bound two, three, or a million different ways, we bind it two, three or a million different ways and then evaluate those million different possible bindings to determine which one is "the best". This makes overload resolution at least NP-HARD in C#, and it took me the better part of a year to implement. We were willing to make that investment because (1) lambdas are awesome, and (2) most of the time people write programs that can be analyzed in a reasonable amount of time and can be understood by humans. So it was worth the cost. But in general, that kind of advanced analysis is not worth the cost.
C# expressions always* have a fixed type, regardless of their surroundings.
You're asking for an expression whose type is determined by whatever it's assigned to; that would violate this principle.
*) except for lambda expressions, function groups, and the null literal.
Unlike Java, in C# type reference doesn't base on the return type. And don't ask me why, Eric Lippert had answered these "why can't C# ..." questions:
because no one ever designed, specified, implemented, tested,
documented and shipped that feature

C# Debugging functions that contain lambda expressions [duplicate]

This question already has answers here:
Why can I not edit a method that contains an anonymous method in the debugger?
(5 answers)
Closed 6 years ago.
I have a function with a lambda expression something like:
int maxOccurrences = ( from field in data select field ).Max( f => f.Occurrences )
P.S. I'm sure that there's a nicer / neater / more idiomatic version of the above statement, it might be nice to know what that might be, although its not important to the question!
If I modify anything else within the function whilst debugging say a Console.Write expression, the debugger states:
Modifying a 'method' which contains a lambda expression will prevent the debug session from continuing while Edit and Continue is enabled.
I was wondering why this might be the case?
I would have thought that the IL generated for the lamba function and the Console.Write statement would be separate and that the Debugger could alter and modify when necessary. Is there some fundamental concept that I'm missing concerning the lamda functionality?
It isn't that it would be impossible to achieve in all cases (I don't think). It would be a monster feature to develop, though.
When you've got LINQ syntax in your method, generally that involves some anonymous method either behind-the-scenes:
// This LINQ query...
var fields = from field in data select field;
// ...is equivalent to this:
var fields = data.Select(f => f);
...or just flat-out in front of the scenes (as in your example):
( from field in data select field ).Max( f => f.Occurrences ) // <- lambda
An anonymous method in turn gets compiled into a type with instance methods to support the code you've written.
In the example above, consider the f => f.Occurrences lambda. This gets compiled into a type with a single instance field whose type is that of the local f in that lambda; this type contains a method that returns f.Occurrences.
So when the code ultimately enumerates over the result of your LINQ query, what's happening is that an instance of this compiler-generated type is being constructed for every field in data and that type's single method which has been generated to support the f => f.Occurrences lambda expression is being called to calculate Max.
The issue with edit-and-continue is that if there's any change to the lambda expressions in the method being edited, this necessitates changing the types generated, which is not an option. One would think this could still be done in the case where nothing is altered about the lambda expressions themselves; as long as the same locals are captured and the anonymous methods are unchanged, it should be feasible to modify a method with these characteristics while debugging just as it is for "normal" methods in VS.
But as you can see, the type generation used to support anonymous methods in general and therefore LINQ queries specifically adds a great deal of complexity to the edit-and-continue process, and in many cases makes it impossible (since it requires changing generated types completely).
I think it was just decided that it wasn't worth the development cost to even bother trying to support this behavior in the limited scenarios where it could hypothetically work.
Or you can simply move to Visual Studio 2015 :)
The "Edit and Continue" feature in VS 2015 allows editing methods with lambda expressions.
You can read about it in more detail here:
http://blogs.msdn.com/b/visualstudioalm/archive/2015/04/29/net-enc-support-for-lambdas-and-other-improvements-in-visual-studio-2015.aspx
There is a really simple way to debug a lamba expression. Convert it to an anonymous method using an inline delegate. Simple. :)

with dynamic, awkward reflection no more?

C# 4.0 introduces dynamic keyword, which will look up at run-time.
Does this mean we'll need awkward reflection no more? If does, Can you show up an example of it?
We'll still have Reflection - using 'dynamic' against regular CLR objects will invoke a Reflection-based dispatcher.
So - we'll still have Reflection, but it'll be easier to do.
Here's an example:
// Via 'dynamic'
dynamic dx = GetSomeCLRObject();
dx.DoSomething();
dx.SomeMember = 2;
// Via Reflection
object x = GetSomeCLRObject();
Type xt = x.GetType();
MemberInfo DoSomethingMethod = xt.GetMethod("DoSomething");
DoSomethingMethod.Invoke(x, null);
PropertyInfo SomeMemberProperty = xt.GetProperty("SomeMember");
SomeMemberProperty.SetValue(x, 2);
I don't know about you, but I like the former. =)
In both these cases, I get no compile-time checking, no Intellisense, no IDE support - but the former case is much more expressive than the latter.
Dynamic dispatch is only one possible use of Reflection. There are many good reasons to interrogate a class for its structure, get information about that structure and visualize in some form or act on it in some way without ever dynamically accessing members. Reflection is here to stay. :)
If you want examples of the dynamic keyword, here is a video from PDC of the man himself talking about it (and other stuff C# 4.0 related).
Dynamic will go a long way to solving problems with methods known only by name, where that name is known and fixed at compile time - but of course, such methods could also be expressed as interfaces if you control the types.
There are cases where dynamic would not help at all:
where the method name isn't known at compile time (i.e. it is loaded from config / user input)
object creation
maybe some generics scenarios
The biggest uses I see for dynamic are:
COM interop (obviously)
generic operator support
duck typing where there is no common interface
DLR interop (see comments)
But it definitely doesn't solve every reflection woe.

Best practice of using the "out" keyword in C#

I'm trying to formalise the usage of the "out" keyword in c# for a project I'm on, particularly with respect to any public methods. I can't seem to find any best practices out there and would like to know what is good or bad.
Sometimes I'm seeing some methods signatures that look like this:
public decimal CalcSomething(Date start, Date end, out int someOtherNumber){}
At this point, it's just a feeling, this doesn't sit well with me. For some reason, I'd prefer to see:
public Result CalcSomething(Date start, Date end){}
where the result is a type that contains a decimal and the someOtherNumber. I think this makes it easier to read. It allows Result to be extended or have properties added without breaking code. It also means that the caller of this method doesn't have to declare a locally scoped "someOtherNumber" before calling. From usage expectations, not all callers are going to be interested in "someOtherNumber".
As a contrast, the only instances that I can think of right now within the .Net framework where "out" parameters make sense are in methods like TryParse(). These actually make the caller write simpler code, whereby the caller is primarily going to be interested in the out parameter.
int i;
if(int.TryParse("1", i)){
DoSomething(i);
}
I'm thinking that "out" should only be used if the return type is bool and the expected usages are where the "out" parameters will always be of interest to the caller, by design.
Thoughts?
There is a reason that one of the static code analysis (=FxCop) rules points at you when you use out parameters. I'd say: only use out when really needed in interop type scenarios. In all other cases, simply do not use out. But perhaps that's just me?
This is what the .NET Framework Developer's Guide has to say about out parameters:
Avoid using out or reference parameters.
Working with members
that define out or reference
parameters requires that the developer
understand pointers, subtle
differences between value types and
reference types, and initialization
differences between out and reference
parameters.
But if you do use them:
Do place all out parameters after all of the pass-by-value and ref
parameters (excluding parameter
arrays), even if this results in an
inconsistency in parameter ordering
between overloads.
This convention makes the method
signature easier to understand.
Your approach is better than out, because you can "chain" calls that way:
DoSomethingElse(DoThing(a,b).Result);
as opposed to
DoThing(a, out b);
DoSomethingElse(b);
The TryParse methods implemented with "out" was a mistake, IMO. Those would have been very convenient in chains.
There are only very few cases where I would use out. One of them is if your method returns two variables that from an OO point of view do not belong into an object together.
If for example, you want to get the most common word in a text string, and the 42nd word in the text, you could compute both in the same method (having to parse the text only once). But for your application, these informations have no relation to each other: You need the most common word for statistical purposes, but you only need the 42nd word because your customer is a geeky Douglas Adams fan.
Yes, that example is very contrived, but I haven't got a better one...
I just had to add that starting from C# 7, the use of the out keyword makes for very readable code in certain instances, when combined with inline variable declaration. While in general you should rather return a (named) tuple, control flow becomes very concise when a method has a boolean outcome, like:
if (int.TryParse(mightBeCount, out var count)
{
// Successfully parsed count
}
I should also mention, that defining a specific class for those cases where a tuple makes sense, more often than not, is more appropriate. It depends on how many return values there are and what you use them for. I'd say, when more than 3, stick them in a class anyway.
One advantage of out is that the compiler will verify that CalcSomething does in fact assign a value to someOtherNumber. It will not verify that the someOtherNumber field of Result has a value.
Stay away from out. It's there as a low-level convenience. But at a high level, it's an anti-technique.
int? i = Util.TryParseInt32("1");
if(i == null)
return;
DoSomething(i);
If you have even seen and worked with MS
namespace System.Web.Security
MembershipProvider
public abstract MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status);
You will need a bucket. This is an example of a class breaking many design paradigms. Awful!
Just because the language has out parameters doesn't mean they should be used. eg goto
The use of out Looks more like the Dev was either Lazy to create a type or wanted to try a language feature.
Even the completely contrived MostCommonAnd42ndWord example above I would use
List or a new type contrivedresult with 2 properties.
The only good reasons i've seen in the explanations above was in interop scenarios when forced to. Assuming that is valid statement.
You could create a generic tuple class for the purpose of returning multiple values. This seems to be a decent solution but I can't help but feel that you lose a bit of readability by returning such a generic type (Result is no better in that regard).
One important point, though, that james curran also pointed out, is that the compiler enforces an assignment of the value. This is a general pattern I see in C#, that you must state certain things explicitly, for more readable code. Another example of this is the override keyword which you don't have in Java.
If your result is more complex than a single value, you should, if possible, create a result object. The reasons I have to say this?
The entire result is encapsulated. That is, you have a single package that informs the code of the complete result of CalcSomething. Instead of having external code interpret what the decimal return value means, you can name the properties for your previous return value, Your someOtherNumber value, etc.
You can include more complex success indicators. The function call you wrote might throw an exception if end comes before start, but exception throwing is the only way to report errors. Using a result object, you can include a boolean or enumerated "Success" value, with appropriate error reporting.
You can delay the execution of the result until you actually examine the "result" field. That is, the execution of any computing needn't be done until you use the values.

Categories

Resources