I am curious to know why when we are doing P/invoke
the dllimport call is in a "["
and not just a class or a function
e.g.:
[DllImport("something.dll",....)]
rather than
DllImport("something.dll,....)
or even
DllImport.import(something.dll...)
I do not want to rewrite it, my questions is what does "[" represent or mean ? what is it called in this instance ? Why is it used ?
In this context, it signifies an "attribute"; DllImportAttribute (MSDN). Simply : it is a syntax already in the language for adding metadata to the code.
The language allows you to define your own attributes, or any from libraries. Attributes can be used on assemblies, types, methods, properties, fields, events, parameters, etc - or restricted to a small subset of that. DllImportAttribute is limited to methods, for example. Most only have meaning when inspected with reflection at runtime, but some re handled directly by the compiler.
DllImport is not a method. It is an attribute. The brackets are just the syntax for applying attributes.
The syntax is specified in appendix B of the C# specification, section B.2.13, Attributes.
Related
In C#, is there any difference between using System.Object in code rather than just object, or System.String rather than string and so on? Or is it just a matter of style?
Is there a reason why one form is preferrable to the other?
string is an alias for global::System.String. It's simply syntactic sugar. The two are exactly interchangable in almost all cases, and there'll be no difference in the compiled code.
Personally I use the aliases for variable names etc, but I use the CLR type names for names in APIs, for example:
public int ReadInt32() // Good, language-neutral
public int ReadInt() // Bad, assumes C# meaning of "int"
(Note that the return type isn't really a name - it's encoded as a type in the metadata, so there's no confusion there.)
The only places I know of where one can be used and the other can't (that I'm aware of) are:
nameof prohibits the use of aliases
When specifying an enum base underlying type, only the aliases can be used
The object type is an alias for System.Object. The object type is used and shown as a keyword. I think it has something to do with legacy, but that's just a wild guess.
Have a look at this MSDN page for all details.
I prefer the use of the lowercased versions, but for no special reasons. Just because the syntax highlighting is different on these "basic" types and I don't have to use the shift key when typing...
One is an alias to the other. Its down to style.
string is an alias for global::System.String, and object for global::System.Object
Providing you have using System; in your class, String / string and Object / object are functionally identical and usage is a matter of style.
(EDIT: removed slightly misleading quote, as per Jon Skeet's comment)
string (with the lowercase "s") is the string type of the C# language and the type System.String is the implementation of string in the .NET framework.
In practise there is no difference besides stylistic ones.
EDIT: Since the above obviously wasn't clear enough, there is no difference between them, they are the same type once compiled. I was explaining the semantic difference that the compiler sees (which is just syntactic sugar, much like the difference between a while and for loop).
There are no difference. There is a number of types, called Primitive Data Types which are threated by compiler in style you mentioned.
Capitalized naming style is ISO naming rule. It's more general, common; forces the same naming rules for all objects in the source without exceptions such C# compiler has.
As of my knowledge, I know that it's a shortcut, it's easier to use string, rather than System.string.
But be careful there's a difference between String and string (c# is case sensitive)
object, int, long and bool were provided as training wheels for engineers that had trouble adapting to the idea that the data types were not a fixed part of the language. C#, unlike the languages that went before it, has no limit on the number of data types you can add. The 'System' library provides a starter kit featuring such useful types as System.Int32, System.Boolean, System.Double, System.DateTime and so on, but engineers are encouraged to add their own. Because Microsoft was interested in quick adoption of their new language, they provided aliases that made it appear as if the language was more 'C'-like, but these aliases are a completely disposable feature (C# would be just as good a language if you removed all the build-in aliases, probably better).
While StyleCop does enforce the use of the legacy C-style aliases, it is a blemish on an otherwise logical set of rules. As of yet, I've not heard a single justification for this rule (SA1121) that wasn't based on dogma. If you think SA1121 is logical, then why is there no buildin type for datetime?
I was reading Inside C#, and i am stumbled upon Type.IsAutoClass.
The documentation says
true if the string format attribute AutoClass is selected for the Type; otherwise, false.
The question is What is AutoClass and how due it impacts a Type?
Note that this is academic question, and there is no practical usage (to best of my knowledge) in projects, I am associated with.
It is part of the TypeAttributes Enumeration:
AutoClass - LPTSTR is interpreted automatically.
And the remarks:
The members of this enumerator class match the CorTypeAttr enumerator as defined in the corhdr.h file.
So, this is used for interop, in how strings constants are interpreted.
By the way - LPTSTR.
I noticed something curious when messing around with nested classes and outputting the name of the type to a console window. I was wondering if someone could explain it a bit for me. When calling GetType() on the main class, it returns what I would expect, which was the name of the class after the relevant namespaces. i.e. Namespace.Namespace.Classname
However, when I call a function from within the enclosing class to return the type of the nested class I get the value returned as this:
Namespace.Namespace.ClassNameEnclosing + ClassNameNested.
Why is it not simply returned as dot notation. Why the + symbol? I am just curious as to what is going on in the background that causes this notation.
Dots are used to denote namespaces. The nested class is still in the same namespace, it's just nested within a class.
I can't tell offhand (from a brief study of ECMA-335) whether an unqualified type name which included a dot would actually be valid in IL; I suspect it would, but it would make all kinds of diagnostics harder to read.
Reflection is not language-specific.
The dot notation (Namespace.Namespace.OuterClassName.InnerClassName) is specific to C#. Reflection must work for every language that you can use to compile to IL. Besides, how can you be sure, when reflecting, that the OuterClassName isn't just another part of the namespace without examining other properties of the Type class?
You ask why is it not simple returned as dot notation? You might as well ask "Why is it not simply returned as IronPython notation", or IronLisp notation, or L# notation, or BOo notation, or...
Learn the notation used in reflection, and you can use it to analyze code written in any language.
In C#, is there any difference between using System.Object in code rather than just object, or System.String rather than string and so on? Or is it just a matter of style?
Is there a reason why one form is preferrable to the other?
string is an alias for global::System.String. It's simply syntactic sugar. The two are exactly interchangable in almost all cases, and there'll be no difference in the compiled code.
Personally I use the aliases for variable names etc, but I use the CLR type names for names in APIs, for example:
public int ReadInt32() // Good, language-neutral
public int ReadInt() // Bad, assumes C# meaning of "int"
(Note that the return type isn't really a name - it's encoded as a type in the metadata, so there's no confusion there.)
The only places I know of where one can be used and the other can't (that I'm aware of) are:
nameof prohibits the use of aliases
When specifying an enum base underlying type, only the aliases can be used
The object type is an alias for System.Object. The object type is used and shown as a keyword. I think it has something to do with legacy, but that's just a wild guess.
Have a look at this MSDN page for all details.
I prefer the use of the lowercased versions, but for no special reasons. Just because the syntax highlighting is different on these "basic" types and I don't have to use the shift key when typing...
One is an alias to the other. Its down to style.
string is an alias for global::System.String, and object for global::System.Object
Providing you have using System; in your class, String / string and Object / object are functionally identical and usage is a matter of style.
(EDIT: removed slightly misleading quote, as per Jon Skeet's comment)
string (with the lowercase "s") is the string type of the C# language and the type System.String is the implementation of string in the .NET framework.
In practise there is no difference besides stylistic ones.
EDIT: Since the above obviously wasn't clear enough, there is no difference between them, they are the same type once compiled. I was explaining the semantic difference that the compiler sees (which is just syntactic sugar, much like the difference between a while and for loop).
There are no difference. There is a number of types, called Primitive Data Types which are threated by compiler in style you mentioned.
Capitalized naming style is ISO naming rule. It's more general, common; forces the same naming rules for all objects in the source without exceptions such C# compiler has.
As of my knowledge, I know that it's a shortcut, it's easier to use string, rather than System.string.
But be careful there's a difference between String and string (c# is case sensitive)
object, int, long and bool were provided as training wheels for engineers that had trouble adapting to the idea that the data types were not a fixed part of the language. C#, unlike the languages that went before it, has no limit on the number of data types you can add. The 'System' library provides a starter kit featuring such useful types as System.Int32, System.Boolean, System.Double, System.DateTime and so on, but engineers are encouraged to add their own. Because Microsoft was interested in quick adoption of their new language, they provided aliases that made it appear as if the language was more 'C'-like, but these aliases are a completely disposable feature (C# would be just as good a language if you removed all the build-in aliases, probably better).
While StyleCop does enforce the use of the legacy C-style aliases, it is a blemish on an otherwise logical set of rules. As of yet, I've not heard a single justification for this rule (SA1121) that wasn't based on dogma. If you think SA1121 is logical, then why is there no buildin type for datetime?
In C#, I am using a library that defines an enum. I would like to allow consumers of my code (in a different assembly) to pass in an enum value as a parameter to one of my functions without having to reference the underlying library themselves.
Is there a way for me to expose the library's enumeration to my consumers?
You could define your own enum with the values you want to support, expose that to your consumers, and simply convert it to the library's enum before you call into it. Since enums are just numbers behind the scenes, it's easy to convert one enum's values to another's.
You can offer an overload that takes an int, describe which values are valid, then perform the cast yourself. Alternatively, you can offer a different enumeration in your library, then convert it before calling into the second library.
I realy don't know, which rational reason is doing this ( combination of "consumer call method from type in my assembly" and "consumer doesn't have my assembly as reference" ), but there are 2 ways.
The first ( recommended ):
You should split your assembly into two. One with enum type definition and the second with the functions. Consumers will reference only "first" assembly.
The second ( not recommended ):
You can use a (sbyte/(u)short/(u)int/(u)long in parameters instead of enums.
But I think, you have a mismatch design of object model.