When are ParameterInfo.IsLcid or ParameterInfo.IsRetval true? - c#

I find this question in Stack Overflow when googleing, but it has been deleted. So I list this question again.
As I can't find the LcidAttribute or RetvalAttribute in BCL, I guess C# hasn't provided the support for locale identifier parameter and return value parameter.
Is that it?
Thanks all.

They are associated with the ParameterAttributes enumeration. Which is used in metadata for the parameter of a method, only a compiler can emit the [modopt].
I do not know of a compiler that actually does this. I have a decent guess at the background though, these attributes are also used in IDL. Which is an interface description language that is used in COM and RPC. Having this option ensures that .NET metadata can also describe the kind of declarations that are written in IDL and can appear in type libraries.
The [lcid] attribute is described here. It doesn't actually describe usage and I've never used it myself. No real idea why you'd use it.
The [retval] attribute is described here. Very important in COM automation method declarations, it marks the parameter that returns the method value. And used by a tool like Tlbimp.exe, it rewrites the method to make that parameter the return value type.

Related

Retrieve custom attributes given to method parameters

I am employing a logic similar to the suggestion present in the Microsoft documentation https://msdn.microsoft.com/en-us/library/cs58sb90(v=vs.110).aspx to retrieve the custom attributes given to the parameter of a method.
However, I find this approach expensive as it uses reflection to retrieve the custom attributes, I am wondering if there is any better approach to this problem than using reflection?
The short answer as far as I am aware is no, reflection is the standard and probably only way to retrieve attributes.
However, attributes are fixed in the type metadata at compile-time, which means you will only ever have to inspect them once for each type during the lifetime of your program, and they won't change in that time unless your code is doing some really wacky runtime type construction (e.g. with Reflection.Emit). Even if you don't know the exact type of any object your code requires the attributes of, you could still cache the type's attributes in a dictionary to save looking them up again, if you're really that concerned about performance.

Retrieve custom attributes of Type in .NET Standard

I'd like to use C#'s reflection and custom attributes to simplify registering a series of types with a central management class (i.e. it provides static methods taking a string key and invoking/retrieving the proper method/parameter for the associated type). Looking at other questions here and a couple places elsewhere, it seems like the best way of doing so is to simply iterate through all public types of the assembly -- since it's intended to be a library -- and check if each type has the proper attribute before adding the relevant values to the underlying Dictionaries. The reflection and iteration will definitely be slow, but I can live with it since it should only occur once.
Unfortunately, I can't figure out how to get an attribute from a type. For methods and assemblies, I can use CustomAttributeExtensions.GetCustomAttribute<MyAttribute>(base) from System.Reflection.Extensions, but that doesn't provide an overload for Type; the same for Assembly.GetCustomAttribute(Assembly, Type) and the .IsDefined(...) methods used in this question. Other suggestions use methods on the Type itself that, from the documentation, seem to be loaded from mscorelib.dll, but it didn't seem to be showing up in Intellisense even after adding the reference and I'm not sure how that .dll interacts with .NET Standard, anyway (as in, does it reduce the ability to run on arbitrary platforms at all?)
Am I missing something obvious, or is it really this hard to get an Attribute back off of a Type?
Try typeof(YourType).GetTypeInfo().GetCustomAttributes();

How to parse source code fragment to System.Type

I have a set of strings like this:
System.Int32
string
bool[]
List<MyType.MyNestedType>
Dictionary<MyType.MyEnum, List<object>>
I would like to test if those strings are actually source code representations of valid types.
I'm in an environment, that doesn't support Roslyn and incorporating any sort of parser would be difficult. This is why I've tried using System.Type.GetType(string) to figure this out.
However, I'm going down a dirty road, because there are so many edge cases, where I need to modify the input string to represent an AssemblyQualifiedString. E.g. nested type "MyType.MyNestedType" needs to be "MyType+MyNestedType" and generics also have to be figured out the hard way.
Is there any helper method which does this kind of checking in .Net 2.0? I'm working in the Unity game engine, and we don't have any means to switch our system to a more sophisticated environment with available parsers.
Clarification
My company has developed a code generation system in Unity, which is not easily changed at this point. The one thing I need to add to it, is the ability to get a list of fields defined in a class (via reflection) and then separate them based on whether they are part of the default runtime assembly or if they are enclosed within #if UNITY_EDITOR preprocessor directives. When those are set, I basically want to handle those fields differently, but reflection alone can't tell me. Therefore I have decided to open my script files, look through the text for such define regions and then check if a field is declared within in them, and if true, put it in a separate FieldInfo[] array.
The one thing fixed and not changeable: All script will be inspected via reflection and a collection of FieldInfo is used to generate new source code elsewhere. I just need to separate that collection into individual ones for runtime vs editor assembly.
Custom types and nested generics are probably the hard part.
Can't you just have a "equivalency map to fully qualified name" or a few translation rules for all custom types ?
I guess you know by advance what you will encounter.
Or maybe run it on opposite way : at startup, scan your assembly(s) and for each class contained inside, generates the equivalent name "as it's supposed to appear" in your input file from the fully qualified name in GetType() format ?
For custom types of other assemblies, please note that you have to do things such as calling Assembly.LoadFile() or pass assembly name in second parameter to GetType() before to be able to load them.
See here for example : Resolve Type from Class Name in a Different Assembly
Maybe this answer could also help : How to parse C# generic type names?
Could you please detail what is the final purpose of project ? The problem is a bit surprising, especially for a unity project. Is it because you used some kind of weird serialization to persist state of some of your objects ?
This answer is more a few recommandations and questions to help you to clarify the needs than a definitive answer, but it can't hold in a single comment, and I think it provide useful informations

PInvoke Implementation on Fields

So today I was browsing around ILSpy to get a better understanding of how .NET performs DllImports on external methods, when I came across something odd:
When searching for references to the enum value PInvokeImpl, which is defined in the System.Reflection.MethodAttributes enumeration, I noticed a matching definition in System.Reflection.FieldAttributes.
Well sure enough, this appears to be more than just a behind-the-scenes, re-use of enumeration values: System.Reflection.FieldInfo has an publicly defined property called IsPinvokeImpl, which specifically checks if this implementation flag is set.
Interestingly enough, the MethodInfo class doesn't even have this property - it must be determined from the MethodImplementationFlags property instead.
Question:
Is it actually possible for a field to be PInvoke implemented, or is this just a stub implementation in the .NET framework for balance between field decorations and method decorations?
If it is possible, can it be done in C#, or is this a feature that requires C++/CLI?
When you look at the MSDN description for FieldAttributes then you'll see it documented as "Reserved for future use". That future has not arrived yet so its intention is not nailed down.
Types like FieldAttributes are not arbitrary, they follow the CLI specification. Ecma-335 nails down what the metadata in a .NET assembly needs to look like and how it should be interpreted. This document does reveal an interesting quirk.
Chapter II.16.1 describes the field attributes, you'll see a close match between the metadata tokens and the FieldAttributes enum. Note however that pinvokeimpl is missing in that chapter.
Chapter II.23.1.5 gives the specific values of the attributes, it has PInvokeImpl with the value 0x2000. Description is "Implementation is forwarded through PInvoke". Compare to II.23.1.10, describes method attributes. It has many values in common with field attributes.
This looks a lot like a copy/paste bug :)
Digging a bit deeper through the .NET Framework source code, the CLR and jitter only ever considers pinvokeimpl on methods. The C# compiler however appears to be based on the CLI spec and actually sets the attribute. Appears in emit.cpp, RegMeta::_DefinePinvokeMap() function, it will set the attribute if this function is called for a field instead of a method. That never actually happens.
From FieldAttributes:
PinvokeImpl Reserved for future use.
So I would say:
Q: Is it actually possible for a field to be PInvoke implemented
A: No

protobuf-net missing has_ function for optional fields?.

We use protocol buffers for communication between native C++ apps, but also between native C++ app and .NET application (all is VS2012) via protobuf-net r666.
We rely in C++ heavily on the has_ functions that are available for an optional element.
E.g. if we have a message with a field optional bool, it can be that it is not set, it is set to true, or it is set to false.
In C++ this can be checked with the function has_field and if set then the content can be fetched with get_field function. If not set, and get_field is called, then the get returns the default, which if not explicitly set is false (for a boolean).
This works perfectly in C++, but, in protobuf-net however, we cannot seem to find the equivalent of the has_ function, and, when the message is received, the field is added to the message and it's content is set to the default, being false. It's not a disaster that the field is there with the default, but the problem is that there is no has_ function to check whether it was set in the message.
Please advise whether this is a bug or whether we missed something in protobuf-net and that this actually is possible
Thx in advance.
Wim
(I know we already covered this in the issue tracker - this is purely for visibility etc)
This relates to generating classes from .proto files, which in the case of protobuf-net is via the protogen tool. By default, it does not create the equivalent of has_* methods, but this can be enabled with the -p:detectMissing switch - which causes it to create *Specified accessors. The naming here is a .NET idiom, with *Specified recognised by some other .NET serializers and internal code. It also generates a private ShouldSerialize* method, which again helps some internal .NET code.
In this specific case, there was a secondary issue with a member called value causing confusion; the csharp.xslt file has now been updated to account for this.
Update: in the fully managed rewrite, the ShouldSerialize*() method is generated by default when using proto2 syntax (the default). No additional parameter is required. The *Specified member is not added (it serves no additional purpose over ShouldSerialize*().
Note that when using proto3, the changes to serialization rules mean that this concept no longer has meaning. A value is serialized if and only if it is not the default, which is always null/false/zero/empty. There is no concept of "the default value but specified". Because of this, the ShouldSerialize*() methods are generally no longer useful, and are not generated. I'm open to making them optionally generated for proto3, with them basically meaning "non-default", if that helps some genuine coding scenario.

Categories