0

Given the example below, is it possible to use () => MyProperty syntax to infer MyClass?

using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace MyNamespace
{
    class Program
    {
        private static void Main(string[] args)
        {
            // This compiles fine:
            var map = new Dictionary<Expression<Func<MyClass, object>>, string>
            {
                // Lambda Expression has a single argument of "MyClass".
                {x => x.MyProperty, "Hello world"}
            };

            // Is is possible to initialize Dictionary using parameter-less lambda?
            var map2 = new Dictionary<Expression<Func<??????>>, string>
            {
                // Can the Lambda be parameter-less (infer MyClass automagically)?
                {() => MyProperty, "Hello world"}
            };
        }
    }

    class MyClass
    {
        public string MyProperty { get; set; }
    }
}

Code also on .NET Fiddle: https://dotnetfiddle.net/OVERm3

8
  • 4
    what if some other class also has SomeProperty ? what should happen then ? Commented Jul 25, 2014 at 21:34
  • @Selman22, "SomeClass" is concrete (it's defined at the bottom). I tried to make the example generic. If I renamed it to "MyClass" and "MyProperty"... would that be clearer? Commented Jul 25, 2014 at 22:03
  • @LeeGrissom, here i give you another concrete class: public class Batman { public string SomeProperty {get;set;} }. The author of this 3rd party library you are using just added it to his library. Oh, and you collegue just added such a cool Batman class also to the project you both are working on. No problem there, i guess, since the class is concrete ;-) Commented Jul 25, 2014 at 22:08
  • @elgonzo, but those additional types would reside in different namespaces, so the compiler would never be confused. I'll include a concrete namespace to make it clearer. Commented Jul 25, 2014 at 22:10
  • @LeeGrissom, you do realize that you make a lot of assumptions about what is possible and what is not possible, and you seem to expect the compiler to work based on these assumptions... Commented Jul 25, 2014 at 22:17

2 Answers 2

4

In short, no. C# doesn't work like that.

Firstly, the token SomeProperty has no meaning in the context of Program.Main where it is being used. None. There is no static property or field on the Program class that matches it, and it's not going to wander off looking for one in other classes no matter how close they are. This is called Lexical Scope, and it's important.

Second, SomeClass.SomeProperty is an instance property, so you can't access it at all without an instance reference. Even methods within the class follow that rule, the language will imply this if you don't specify it yourself.

And finally, the LambdaExpression is invalid because it is not possible to compile it to functioning code. Lambdas are not magic, they follow the same rules internally that all the rest of the code does. Sure the compiler does some fun things to make them happen, and type inference is pretty cool, but the general rule is: if you can't do it in other code, you can't do it in a lambda.

So the real question is, what exactly are you trying to achieve here? What problem does this solve for you, and how? If we knew that, perhaps we could offer some alternatives.

Sign up to request clarification or add additional context in comments.

1 Comment

+1, Thank you for the link (and thanks for the constructive response). (Substituting My for Some). I was essentially wondering if there was a way to have MyClass type fall within the lexical scope of the initialization. But ultimately, I was after a way to export property names of MyClass to something else (with spaces, capitalized, modified terminology). I can't modify MyClass.
0

() => MyProperty means "Given nothing, evaluate to MyProperty". If MyProperty was a local property, then that could make sense, but it is not equivalent to x => x.MyProperty, which says "Given x, evaluate to x.MyProperty.

Another possibility is if x is already defined somewhere else. You could say () => x.MyProperty. This would "capture" x, though you could run into problems if you're not careful, and it adds needless complexity.

Basically, if you're looking for a shorthand way to avoid typing the lambda parameter name twice, there isn't really one.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.