The CLI includes two access modifiers "FamilyAndAssembly" (which allows access to derived types that are in the same assembly) and "FamilyOrAssembly" (which allows access to types if they are derived, and also allows access to types if they
are in the same assembly). The concepts are explained well here:
VB and C# already have syntax for FamilyOrAssembly ("Protected Friend"). Please add syntax to allow VB to express FamilyAndAssembly.
VB will add two new access modifiers, which are exact transliterations of the CLI keywords...
The pretty-lister will not turn "Protected Friend" into "ProtectedOrFriend". However, if the user types "private protected" (or whatever syntax C# chooses) then it will pretty-list the entire file into C#. JOKE. No it won't. But
it may pretty-list the C# syntax into "ProtectedAndFriend".
Here are some code samples:
ProtectedAndFriend Sub f()
Friend Property p As T
' means anyone in the assembly can see it,
' but only those who also derive can set it
Protected Property p As T
' means it's a protected property, but
' only my assembly can set it
Alex wrote, "Around Private Protected, I really feel like we make a mistake if we choose our VB syntax with the arbitrary choice that C# made so that it could look like C++. We should embrace this as one of those times where VB’s trend towards verbosity
leads naturally to a design whose meaning is obvious at first glance. We don’t want to get stuck in a design rut where we’re OK with C# being clearer than VB where terseness pays off, but not vice versa where verbosity pays off – by definition, then, VB will
always be less clear than C#."
Neal observed that the sense of "And/Or" is confusing. It might be a logical And of the permissions, or a logical And of the restrictions. Nevertheless, the CLI has chosen a canonical sense, and we're copying it.
OTHER DESIGNS CONSIDERED
protected if internal
internal && protected // also "internal || protected"
internal and protected // also "internal or protected"
internalAndProtected // also "internalOrProtected"
ProtectedAndFriend ' also "ProtectedOrFriend"
Protected And Friend ' also "Protected Or Friend"
ProtectedFriend ' rejected because it's just one space away from "Protected Friend"
FamilyAndAssembly ' also "FamilyOrAssembly"
Protected OnlyIn Friend
Protected But Friend
Protected If Friend
Protected When Friend
Protected Xor Friend ' just a joke... :)
double d = 10.5;
int x = (int)d;
The VB version is slower than C#. Indeed, any time we call CInt, the compiler always codegens a call to Math.Round. Even CInt(Math.Round(x)) gets compiled into Math.Round(Math.Round(x)).
Please allow us to write fast integer casts in VB.
: Any time the compiler generates an implicit call to Math.Round (i.e. as part of
CInt, CLong, CULong, CUint
), and if the argument of that implicit call is one of a list of math functions known to return a whole number, then omit the outer call to Math.Round. The list of known math functions is:
Round(d), Round(d,MidpointRounding), Truncate(d), Floor(d), Ceiling(d), VisualBasic.Fix(d), VisualBasic.Int(d)
: If the user writes
then we will emit
dependent on the current project-level "check-overflow" settings. (TODO: verify that
has exact same semantics as
, including negative values, superlarge doubles and exceptions, NaN, Infinity). Also do likewise for
conv.i1, conv.i2, conv.i4, conv.i8
and for their unsigned versions, and for both checked and unchecked versions.
This is a compiler optimization, pure and simple. It adds no new syntax or concepts or library functions. We identify targeted scenarios and generate optimal IL in those cases where semantics would not be affected. This seemed the cleanest approach. Specifically,
it seemed better than adding any of the following syntaxes:
d As Integer
Will it be better to special-case just one of these combinations? e.g. conv.i4 on CInt(Truncate(double))? Or is it better to just do all of them? Default answer: "yes do all of them", and only scale back if the compiler-dev comes back and says it's
There are other possible concerns, e.g. what happens if it turns out that the semantics of conv.i4 are actually different from ALL of the Math.Round-like functions? What if it turns out that it's really hard to implement every case? What if expression-trees
throw a wrench in the works? Well, when devs set about implementing the feature, then we can come back to check.