First, yes, I have seen these posts:
Is there an easy way in C# to have conditional compilation symbols based on OS version
Conditional compilation depending on the framework version in C#
but they do not target the direction I am looking for.
What I am looking for specifically is variable _type_ qualification via OS version:
public struct REPASTESPECIAL
{
UInt32 dwAspect;
#if WINVER >= 6.0
UIntPtr dwParam;
#else
UInt32 dwParam;
#endif
}
I do not wish to revert to something like this:
public struct REPASTESPECIAL<T>
{
UInt32 dwAspect;
T dwParam;
}
// return type by OS version
public static Type GetRePasteSpecial_ParamType()
{
if (Environment.OSVersion.Version.Major >= 5) return typeof(IntPtr);
else return typeof(UInt32);
}
...as that would permit programmers to use any object of Type T when I desire dwParam to be an IntPtr or an UInt32 object only, but if I must then so be it, and make this a reference for others looking for the same.
No - conditional compilation works at compile time, whereas it looks like you're after something which works at execution time.
EDIT: Just thinking about it, you could use conditional compilation in one sense: you could encapsulate this as far as possible in its own assembly, and compile it two ways, producing two separate assemblies. Then at install time (or whatever) install the right assembly. It's hard to know how feasible that is without knowing what kind of app you're writing though.
Answer to: "I have some ugly logic that I'm afraid will be misused when I expose it to others"
Consider exposing nice and usable API which does not let any misuse. Declare all interop types as inner classes and structures of implementation f you nice API, there is not much value to make innermost classes like REPASTESPECIAL to be publicly visible/usable.
This way you can hide ugly class/struct types and dynamically pick OS specific implementation if needed.
If this educational project - than it would be good place to learn about dependency injection to configure correct implementation at run-time.
Related
A quick Google search for "instrinsic attribute c#" only returns articles about other attributes, such as [Serializable]. Apparently these are called "intrinsic attributes".
However, there is also an attribute in C# that is itself called [Intrinsic] and I'm trying to figure out what exactly it is and how it works. It doesn't exist on the common attributes page of the .NET Documentation, or anywhere else in the documentation as far as I can see.
This attribute is used inside of .NET Core in several places, for example, in the System.Numerics.Vectors folder, such as Vector2_Intrinsics.cs. Code snippet:
[Intrinsic]
public Vector2(float x, float y)
{
X = x;
Y = y;
}
Here's what I've managed to find after a very limited search through dotnet/corefx repository on github.
[Intrinsic] marks methods, properties and fields that can be potentially replaced/optimized by JIT. Source code comments say something similar (IntrinsicAttribute.cs):
Calls to methods or references to fields marked with this attribute may be replaced at some call sites with jit intrinsic expansions. Types marked with this attribute may be specially treated by the runtime/compiler.
Purpose
For core developers, [Intrinsic] serves at least two purposes:
it notifies the developer that the code of the marked field, method or property can be replaced by VM. So, if the code changes, the change should probably be introduced in both places;
it is used as a flag for JIT-optimizer to quickly identify methods that can potentially be optimized.
To give a rough example: JIT-optimizer can replace Enum.HasFlag with a simple bitwise comparison in some cases and not in the others. To do this it needs to identify the method as Enum.HasFlag, check some conditions and replace it with a more optimal implementation. The optimizer can identify the method by name, but, for performance reasons, it's better to filter out methods by a simple flag before performing string comparisons.
Usage
The attribute is only relevant to core developers. You should only use it in an internal class and only in the case when you want to propose very specific JIT-level optimizations for it. [Intrinsic] is pretty much restricted to a small set of widely used .Net classes, that, for some reason, can't be optimized by other means.
from the comments: I'm planning to propose a Color struct for .NET Core which needs to behave similarly to other built-in types for consistency.
You should probably not use [Intrinsic] in your initial proposal. After it passes, you can think about optimization, and if you have a valid scenario when Color will benefit from low level optimizations, you can suggest using [Intrinsic] on some of its methods or properties.
How It Works
Here's how [Intrinsic] is currently used in core:
it is defined as a well-known attribute (wellknownattributes.h):
case WellKnownAttribute::Intrinsic:
return "System.Runtime.CompilerServices.IntrinsicAttribute";
VM parses it and sets the IsJitIntrinsic flag to true for a method (methodtablebuilder.cpp):
if (bmtProp->fIsHardwareIntrinsic || (S_OK == GetCustomAttribute(pMethod->GetMethodSignature().GetToken(),
WellKnownAttribute::Intrinsic,
NULL,
NULL)))
{
pNewMD->SetIsJitIntrinsic();
}
this flag is used to set another flag in method attributes (jitinterface.cpp):
if (pMD->IsJitIntrinsic())
result |= CORINFO_FLG_JIT_INTRINSIC;
this flag is later used to filter out methods which are obviously not intrinsic (importer.cpp):
if ((mflags & (CORINFO_FLG_INTRINSIC | CORINFO_FLG_JIT_INTRINSIC)) != 0)
{
const bool isTail = canTailCall && (tailCall != 0);
call = impIntrinsic(newobjThis, clsHnd, methHnd, sig, mflags, pResolvedToken->token, readonlyCall, isTail,
pConstrainedResolvedToken, callInfo->thisTransform, &intrinsicID, &isSpecialIntrinsic);
impIntrinsic then calls lookupNamedIntrinsic to identify (mostly by name) methods that really (not just potentially) should be optimized;
after all of that importer can perform optimizations based on method. For example, optimization for Enum.HasFlag (importer.cpp):
case NI_System_Enum_HasFlag:
{
GenTree* thisOp = impStackTop(1).val;
GenTree* flagOp = impStackTop(0).val;
GenTree* optTree = gtOptimizeEnumHasFlag(thisOp, flagOp);
if (optTree != nullptr)
{
// Optimization successful. Pop the stack for real.
impPopStack();
impPopStack();
retNode = optTree;
}
else
{
// Retry optimizing this during morph.
isSpecial = true;
}
break;
}
DISCLAIMER: as far as I can tell, the attribute's behaviour is not properly documented anywhere and, thus, is subject for change. The description above is only relevant to code currently in master, this part of core is actively developed and the whole process can be changed in the future.
History
Here's a short timeline of [Intrinsic] based on github repository history:
At some time before 2014 [JitIntrisic] attribute was introduced as a part of System.Numerics with a goal to support new processor instructions (see How does JitIntrinsicAttribute affect code generation?).
On June 6, 2016, Chris McKinsey opened an issue #5626. "Optimize enum1.HasFlag(enum2) into inline bittest without boxing allocations when types are the same". At the time, Enum.HasFlag had a well-known performance issues (see What is it that makes Enum.HasFlag so slow?).
While working on the issue Andy Ayers suggested to introduce a universal mechanism to introduce JIT intrinsics (Issue #13813: Add more flexible method for specifying jit instrinsics)
This led to two pull requests: New jit intrinsic support introduced the general mechanics for [Intrinsic] and JIT: optimize Enum.HasFlag implemented it for Enum.HasFlag. I suggest going through both of them as they are extremely illustrative on the changes that come with [Intrinsic].
Later, during the discussion about moving Vector classes to the CoreLib it was suggested that [JitIntrinsic] isn't used anywhere and should be replaced/removed:
#jkotas: We should not need the JitIntrinsicAttribute. As far as I know, this attribute was future proofing, never used for anything real. We should delete it, and use the IntrinsicAttribute from CoreLib instead.
Promptly, [JitIntrinsic] was removed and replace by [Intrinsic] (Replace JitIntrinsicAttribute with IntrinsicAttribute). That's how this attribute came to be in Vector2.
Explanation:
Special types are indicated to the compiler using the
IntrinsicAttribute custom attribute. If a type is annotated with the
IntrinsicAttribute attribute, the compiler knows not that the
implementation for the given type will be present at runtime.
Methods for types marked as Intrinsic can declare methods to be
extern, in which case the implementation is assumed to be available at
runtime.
Source: MSIL to JavaScript Compiler, section 4.4.1.1
Link: http://tenpow.com/Academics/MSIL2JS/MSIL2JS.pdf
In general, I would suggest not to care about it, nor use it for your own classes.
I am refactoring some source code and got a task to remove preprocessor compiling. I have now searched internet for some days, but haven't found any good idea how to do that. I am also quite new to C#.
So the problem is following, I have different interfaces (classes) for every device and "ControlLogic" class needs to use only one of them at the time. Device is chosen on program run-time.
So far "device" variable (also used globally) is used in a lot of places and considering renaming that doesn't make sense to me. Also all device interfaces (classes) are derived from base class, but interface classes does implement different methods for them.
public class ControlLogic
{
#if FIRST_DEVICE
public FirstDeviceInterace device = null;
#elif SECOND_DEVICE
public SecondDeviceInterface device = null;
#elif THIRD_DEVICE
public ThirdDeviceInterface device = null;
#endif
// One example method
public void startDevice()
{
if (device != null)
{
#if (FIRST_DEVICE || SECOND_DEVICE)
device.startDevice();
#endif
#if THIRD_DEVICE
device.startThirdDevice();
#endif
}
}
// More code.....
}
So what is the best way to remove preprocessor compiling?
I've faced with a similar task a few months ago: large C# code base and extensive preprocessor directives usage. Manual refactoring looked like a long boring monkey job there.
I've failed with unifdef, sunifdef and coan C tools because of C# syntax specifics like #region and some others. In the long run I've made my own tool undefine. It uses regexp to parse the preprocessor directives and sympy python library to simplify logical expression. It works good for me on large 10M lines code base.
I understand that the three device types do not have a common base class or interface. You cannot just pick one of the three at runtime and type all variables with a base type.
Here are a few options:
Find a way to a a common base type.
If you cannot modify the classes (or it would be inappropriate for some reason) write a wrapper. That wrapper can have any structure you like. You could have one wrapper per device class with a common base type.
Use dynamic. This can be a quick fix at the cost of less tooling help (less autocompletion, less documentation at hand, less quick static error checking).
Using #if to solve this problem is very unusual. It is problematic because the amount of testing to even make sure the code compiles has now tripled. You also need multiple binaries.
Note that the following are examples of the rare cases where dotNet reflector does not disassemble correctly. In the vast majority of cases it works perfectly, and I am not suggesting this is necessarily a bug in reflector. It may be a result of protection or obfuscation or unmanaged code on the assemblies in question.
I try to disassemble System.Web.UI.WebControls.XmlHierarchicalEnumerable in dotnet reflector. The generics seems all screwed up, eg:
// Nested Types
[CompilerGenerated]
private sealed class GetEnumerator>d__0 : IEnumerator<object>,
IEnumerator, IDisposable
{
// Fields
private int <>1__state;
private object <>2__current;
public XmlHierarchicalEnumerable <>4__this;
public IEnumerator <>7__wrap2;
public IDisposable <>7__wrap3;
public XmlNode <node>5__1;
In other assemblies I sometimes get little squares (I know these usually stand for 'unknown symbol') in place of class names, eg:
dictionary1.Add("autopostbackonselect", 0x34);
ᜀ.ᜌ = dictionary1;
}
if (ᜀ.ᜌ.TryGetValue(key, out num))
{
switch (num)
What gives ? Anyone know ?
In the first example, this is completely expected. These classes are used for the implementation of IEnumerable<T> when using the yield return statements. It generates classes which store the state and get the new values when MoveNext is called on the IEnumerator<T> instance output by the IEnumerable<T>.GetEnumerator implementation (you will note they are one in the same).
It should be noted that what you are seeing is completely legal naming syntax from a CLR perspective. From a C# perspective though, it is not legal. However, since these classes are internal and you will never need access to them directly (only through interface implmentations), there is no need for them to be legal C# names.
As for the second, I haven't seen that behavior, it's possible that the assembly is obfuscated, but I've not seen that in .NET in any version. If you clarify the assemblies (.NET framework or not) in which version of the .NET framework you are looking at, as well as what version of reflector you are using, it would help.
I have seen this before when looking at assemblies that have been Obfuscated. Quite often during this process variable names are unreadable to the human eye, thus resulting in a unknown character.
This assembly might have been Obfuscated, you can check these links http://cooprotector.com/ http://intelliside.com/
There's quite a few things being autogenetated by the compiler. Auto properties, anonymous types/methods and emumerators based on enumerator blocks. They All need a name and that should be one that does not clash with something names by the developer. Since <>_ is a perfectly legal name in CLR terms but not in C# prefixing anything autogenetated and named with <>_ ensures that the compiler wont accidentally choose a name already used by the developer.
When learning C# for the first time, I was astonished that they had no support for macros in the same capacity that exists in C/C++. I realize that the #define keyword exists in C#, but it is greatly lacking compared to what I grew to love in C/C++. Does anyone know why real macros are missing from C#?
I apologize if this question is already asked in some form or another - I promise I spent a solid 5 minutes looking for duplicates before posting.
from the C# faq.
http://blogs.msdn.com/CSharpFAQ/archive/2004/03/09/86979.aspx
Why doesn't C# support #define macros?
In C++, I can define a macro such as:
#define PRODUCT(x, y, z) x * y * z
and then use it in code:
int a = PRODUCT(3, 2, 1);
C# doesn't allow you to do this. Why?
There are a few reasons why. The first is one of readability.
One of our main design goals for C# is to keep the code very readable. Having the ability to write macros gives the programmer the ability to create their own language - one that doesn't necessarily bear any relation to what the code underneath. To understand what the code does, the user must not only understand how the language works, but he must also understand all of the #define macros that are in effect at that point in time. That makes code much harder to read.
In C#, you can use methods instead of macros, and in most cases, the JIT will inline them, giving you the same performance aspect.
There's also a somewhat more subtle issue. Macros are done textually, which means if I write:
int y = PRODUCT (1 + 2, 3 + 4, 5 + 6)
I would expect to get something that gives me 3 * 7 *11 = 231, but in fact, the expansion as I've defined it gives:
int y = 1 + 2 * 3 + 4 * 5 + 6;
which gives me 33. I can get around that by a judicious application of parenthesis, but its very easy to write a macro that works in some situations and not in others.
Although C# doesn't strictly speaking have a pre-processor, it does have conditional compilation symbols which can be used to affect compilation. These can be defined within code or with parameters to the compiler. The "pre-processing" directives in C# (named solely for consistency with C/C++, despite there being no separate pre-processing step) are (text taken from the ECMA specification):
#define and #undef
Used to define and undefine conditional compilation symbols
#if, #elif, #else and #endif
Used to conditionally skip sections of source code
#line
Used to control line numbers emitted for errors and warnings.
#error and #warning
Used to issue errors and warnings.
#region and #endregion
Used to explicitly mark sections of source code.
See section 9.5 of the ECMA specification for more information on the above. Conditional compilation can also be achieved using the Conditional attribute on a method, so that calls to the method will only be compiled when the appropriate symbol is defined. See section 24.4.2 of the ECMA specifcation for more information on this.
Author: Eric Gunnerson
So that you can have fun typing THIS over and over and over again.
// Windows presetation foundation dependency property.
public class MyStateControl : ButtonBase
{
public MyStateControl() : base() { }
public Boolean State
{
get { return (Boolean)this.GetValue(StateProperty); }
set { this.SetValue(StateProperty, value); }
}
public static readonly DependencyProperty StateProperty = DependencyProperty.Register(
"State", typeof(Boolean), typeof(MyStateControl),new PropertyMetadata(false));
}
Obviously the designers of C# and .NET never actually use any of the libraries or frameworks they create. If they did, they would realize that some form of hygenic syntactic macro system is definitely in order.
Don't let the shortcomings of C and C++'s lame macros sour you on the power of compile time resolved code. Compile time resolution and code generation allows you to more effectively express the MEANING and INTENT of code without having to spell out all of the niggling details of the source code. For example, what if you could replace the above with this:
public class MyStateControl : ButtonBase
{
public MyStateControl() : base() { }
[DependencyProperty(DefaultValue=true)]
bool State { get; set; }
}
Boo has them, OcamML (at least Meta ML) has them, and C and C++ has them (in a nasty form, but better than not having them at all). C# doesn't.
C++-style macros add a huge amount of complexity without corresponding benefit, in my experience. I certainly haven't missed them either in C# or Java. (I rarely use preprocessor symbols at all in C#, but I'm occasionally glad they're there.)
Now various people have called for Lisp-style macros, which I know little about but certainly sound rather more pleasant than C++-style ones.
What do you particularly want to do with macros? We may be able to help you think in a more idiomatically C# way...
C# is aimed at wider audience (or in other term, consumer base) than C++, C or ASM. The only way of achieving this goal is reaching programmers considerably less skilled. Therefore, all the powerful but dangerous tools are taken away. I.e. macros, multiple inheritance, control over object lifetime or type-agnostic programming.
In a very same way matches, knives and nailguns are useful and necessary, but they have to be kept out of reach of children. (sadly, arsons, murders, memory leaks and unreadable code still do happen).
And before accusing me of not thinking C#, how many times have you wrote that:
protected int _PropOne;
public int PropOne
{
get
{
return _PropOne;
}
set
{
if(value == _PropOne) { return; }
NotifyPropertyChanging("PropOne");
_PropOne = value;
NotifyPropertyChanged("PropOne");
}
}
With macros, every time those 16 lines would look like that:
DECLARE_PROPERTY(int, PropOne)
DECLARE_PROPERTY(string, PropTwo)
DECLARE_PROPERTY(BitmapImage, PropThree)
Macros in C / C++ were used to define constants, produce small inline functions, and for various things directly related to compiling the code (#ifdef).
In C#, you have strongly typed constants, a smart enough compiler to inline functions when necessary, and knows how to compile stuff the right way (no precompiled header nonsense).
But there's no particular reason why you couldn't run your CS file through the C preprocessor first if you really wanted to :)
As a long time C# programmer who went off to learn C++ for a while, I now miss rich support for metaprogramming C#. At least, I now have a more expansive appreciation for what metaprogramming can mean.
I would really like to see the kind of macro support that's instilled in Nemerle in C#. It seems to add a very natural and powerful extension capability to the language. If you haven't looked at it, I really recommend doing so.
There are some great examples on Wikipedia.
Macros are overused in C++ but they still have their uses, however most of these uses are not relevant in C# due to reflection and the better integrated use of exceptions for error reporting.
This article compares perl and lisp macros but the point is still the same: Text level macros (perl/c++) cause massive problems compared to source level macros (lisp)
http://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.html
Braver people than me have rolled their own macro like system in c# http://www.codeproject.com/KB/recipes/prepro.aspx
Macros are a tool for the days when most programmers were smarter than the compiler. In C/C++, there are still some cases where this is true.
Nowdays, most programmers aren't as smart as the C# compiler/runtime.
You can do some thing you do with macros like PropertyChanged with ways like this
If thats better than macros ?
Thats a question YOU must decide :)
Anyone who agrees with the idea that macros are bad should read the book, "With Folded Hands." http://en.wikipedia.org/wiki/With_Folded_Hands It tells a story about how we can keep people from doing stupid things all the way to the point of preventing them from doing very wise things.
While I like C#, I do really hate that it contributes to the stupidification of actual software engineers. So, yes, leave macros to the professionals. While we're at it, leave the naming of variables to professionals, too. That can make for some really unreadable code. To follow the full statement of "code must be ultimately readable" all variables should be named A-Z, followed by a-z (or some other arbitrary construct like only nouns). Because some unskilled person may name their variable "SomethingUsefulButNotAllowedByTheCompilerBecauseSomeUsersMayDoDumbThings".
I went through all the posts on reflection but couldn't find the answer to my question.
What were the problems in the programming world before .NET reflection
came and how it solved those problems?
Please explain with an example.
It should be stated that .NET reflection isn't revolutionary - the concepts have been around in other framework.
Reflection in .NET has 2 facets:
Investigating type information
Without some kind of reflection / introspection API, it becomes very hard to perform things like serialization. Rather than having this provided at runtime (by inspecting the properties/fields/etc), you often need code-generation instead, i.e. code that explicitly knows how to serialize each of your types. Tedious, and painful if you want to serialize something that doesn't have a twin.
Likewise, there is nowhere to store additional metadata about properties etc, so you end up having lots of additional code, or external configuration files. Something as simple as being able to associate a friendly name with a property (via an attribute) is a huge win for UI code.
Metaprogramming
.NET reflection also provides a mechanism to create types (etc) at runtime, which is hugely powerful for some specific scenarios; the alternatives are:
essentially running a parser/logic tree at runtime (rather than compiling the logic at runtime into executable code) - much slower
yet more code generation - yay!
I think to understand the need for reflection in .NET, we need to go back to before .NET. After all, modern languages like like Java and C# do not have a history BF (before reflection).
C++ arguably has had the most influence on C# and Java. But C++ did not originally have reflection and we coded without it and we managed to get by. Occasionally we had void pointer and would use a cast to force it into whatever type we wanted. The problem here was that the cast could fail with terrible consequences:
double CalculateSize(void* rectangle) {
return ((Rect*)rectangle)->getWidth() * ((Rect*)rectangle)->getHeight());
}
Now there are plenty of arguments why you shouldn't have coded yourself into this problem in the first place. But the problem is not much different from .NET 1.1 with C# when we didn't have generics:
Hashtable shapes = new Hashtable();
....
double CalculateSize(object shape) {
return ((Rect)shape).Width * ((Rect)shape).Height;
}
However, when the C# example fails it does so with a exception rather than a potential core dump.
When reflection was added to C++ (known as Run Time Type Identification or RTTI), it was hotly debated. In Stroustrup's book The Design and Evolution of C++, he lists the following
arguments against RTTI, in that some people:
Declared the support unnecessary
Declared the new style inherently evil ("against the spirit of C++")
Deemed it too expensive
Thought it too complicated and confusing
Saw it as the beginning of an avalanche of new features
But it did allow us to query the type of objects, or features of objects. For example (using C#)
Hashtable shapes = new Hashtable();
....
double CalculateSize(object shape) {
if(shape is Rect) {
return ((Rect)shape).Width * ((Rect)shape).Height;
}
else if(shape is Circle) {
return Math.Power(((Circle)shape).Radius, 2.0) * Math.PI;
}
}
Of course, with proper planning this example should never need to occur.
So, real world situations where I've needed it include:
Accessing objects from shared memory, all I have is a pointer and I need to decide what to do with it.
Dynamically loading assemblies, think about NUnit where it loads every assembly and uses reflection to determine which classes are test fixtures.
Having a mixed bag of objects in a Hashtable and wanting to process them differently in an enumerator.
Many others...
So, I would go as far as to argue that Reflection has not enabled the ability to do something that couldn't be done before. However, it does make some types of problems easier to code, clearer to reader, shorter to write, etc.
Of course that's just my opinion, I could be wrong.
I once wanted to have unit tests in a text file that could be modified by a non-technical user in the format in C++:
MyObj Function args //textfile.txt
But I couldn't find a way to read in a string and then have the code create an object instance of the type represented by the string without reflection which C++ doesn't support.
char *str; //read in some type from a text file say the string is "MyObj"
str *obj; //cast a pointer as type MyObj
obj = new str; //create a MyObj
Another use might be to have a generic copy function that could copy the members of an class without knowing them in advance.
It helps a lot when you are using C# attributes like [Obsolete] or [Serializable] in your code. Frameworks like NUnit use reflection on classes and containing methods to understand which methods are tests, setup, teardown, etc.