Replies: 17 comments
-
It's very difficult to tell whats going on from that snippet. Can you show a fuller sample (or even a sample solution)? And can you tell us which errors the compiler issued? |
Beta Was this translation helpful? Give feedback.
-
What is You can't pass // error: use of unassigned variable factorial
Func<int, int> factorial = x => x <= 1 ? 1 : x * factorial(x-1); |
Beta Was this translation helpful? Give feedback.
-
You can do this: StubINcuOneSession session = null;
session = new StubINcuOneSession()
{
GetCourseOfferingInt64 = (arg) => NcuOneCourseOffering.Create(session, arg)
}; |
Beta Was this translation helpful? Give feedback.
-
Hi. "this" was simply an attempt to define the lambda so that it refers to the object being initialized, clearly this isn't how its being interpreted. So I also tried "session" and as you know that fails too because "session" isn't (yet) initialized.
Hmm, yes that works and will do for me - but I'm not clear why it cares about "session" being initialized because we're defining a lambda - that is access to the "session" is deferred...so "session" won't be accessed until the initialization { } block has completed (at which point "session" will no longer be unintialized). I mean we can refer to "this" in constructors... |
Beta Was this translation helpful? Give feedback.
-
BTW, as an aside, there's an important difference between "This is a bug" and "There is no reason this shouldn't be allowed" There are million things that are not in C#, for which there are "no reason they shouldn't be allowed". However, nobody has put in the time to implement them, so that's the way they will remain for now. They are not bugs. The Roslyn compiler does have a few bugs. They are cases where its behaviour does not meet that of the specification. They are generally either not known about, or known about, and to difficult to fix, or known about, and to dangerous to fix as it may break someones code. There's also cases which might be considered to be more bugs in the specification than in the compiler. |
Beta Was this translation helpful? Give feedback.
-
True but note I did not say it was a bug, I asked if it was. |
Beta Was this translation helpful? Give feedback.
-
Not necessarily. What if the constructor started an asynchronous operation that would call the function before session had been initialised? |
Beta Was this translation helpful? Give feedback.
-
What makes sure it's deferred until after the variable has been initialized? For example, the constructor of public StubINcuOneSession()
{
Task.Run(() => GetCourseOfferingInt64(null));
} (Yes, the above code is not thread-safe, but with some additions it could be.) If you ignore multithreading, I think your code would be safe, but it's enough to change it only a bit to make it unsafe again:
I don't think it would be a good idea to have such fiddly rules about what is allowed, where almost any small modification changes working code to code that does not compile. |
Beta Was this translation helpful? Give feedback.
-
Fair enough so let me now ask why is it permitted to refer to "this" within a constructor but there's no analogous mechanism for referring to "this" within a property initialization block? In the initialization block an instance does exist at the point when the property setters are being called (else the property setters could not actually be called). So is there scope to (somehow) allow property initialization blocks to refer to "this" - the instance that were initializing? |
Beta Was this translation helpful? Give feedback.
-
@svick - Well as we know we can refer to "this" within a constructor because "this" is a real and valid reference inside a constructor. It also seems to me that there is a real and valid instance when an initialization block is entered. I guess I'm now asking can we provide a way in C# for a property initialization block to refer to the instance that's being initialized? |
Beta Was this translation helpful? Give feedback.
-
A constructor would be fairly useless if it couldn't reference instance members. But you can't refer to The C# language doesn't offer any method to refer to the instance you are currently initializing from within an object initializer. |
Beta Was this translation helpful? Give feedback.
-
Sure so can support for this be considered? |
Beta Was this translation helpful? Give feedback.
-
In fact it seems that "this" cannot be used (is always regarded as illegal) within a property initializer block. This suggests that it could be purposed to mean "the instance we're initializing" and not be a breaking change, is that true? |
Beta Was this translation helpful? Give feedback.
-
Sure you can: public class B {
public C Value { get; set; }
}
public class C {
public void M() {
var b = new B {
Value = this // refers to the current instance of C
};
}
} |
Beta Was this translation helpful? Give feedback.
-
@HaloFour - My apologies, I was incorrect - me test example here was not right. You're quite right and "this" is legal but already means something (else). |
Beta Was this translation helpful? Give feedback.
-
@Korporal |
Beta Was this translation helpful? Give feedback.
-
@YairHalberstadt - Well I wish I had the time - sadly I do not, so if anyone else cares then please do else - no big deal. |
Beta Was this translation helpful? Give feedback.
-
Hi,
Can someone explain why this is not allowed:
The field "GetCourseOfferingInt64" is not static, it's an instance field of a Func type (this is actually trying to leverage Fake assembly support in VS).
Passing in "session" instead of "this" is also illegal but in each case the reference (this or session) won't actually be touched UNTIL the GetXXX operation is called on the created instance because this is a lambda.
I don't see why this isn't legal?
Beta Was this translation helpful? Give feedback.
All reactions