Sadly I was unable to attend, but watching a few videos over the weekend is enough to get my juices flowing for what is coming down the pike for .NET and ASP.NET and C#. Here are a few notes and links:
Amazingly cool stuff coming up for .NET:
Next Generation of .NET for Building Applications
- .NET Native: (22:40) will eventually be available beyond Win 8 RT apps
- SIMD: (36:00) up to 8x performance improvement in parallel operations on multiple data streams
Future of Visual Basic and C#
- Roslyn
- super fast in-memory next generation .NET compiler
- inline renaming - wow!
- open source - on codeplex
- C#
- primary ctor: public class Point(int h, int w)
- getter only auto property: public int Height { get; } = h;
Even more amazingly cool stuff coming for ASP.NET:
The Future of .NET on the Server (intro)
The Future of .NET on the Server (deep dive)
ASP.NET vNext
Oh so much to learn and play with. It’s a good time to be alive!
There are a variety of reasons one might wish to use unmanaged memory in C#, taking advantage of the Marshal class and it’s powerful AllocHGlobal method. The reasons are less important here than the how, at least the how I have learned to do so.
First, you need to know about the word blit and Microsoft’s usage of that word: blittable types. I’ll wait while you catch up.
Next, you need to understand how to construct a complex value type that Microsoft likes to call a “formatted value type.” [sic] To create a formatted value type, you will need to use the StructLayout attribute and the FieldOffset attribute. While not strictly required, these attributes will keep you from wasting precious memory. Here’s an example:
[StructLayout(LayoutKind.Explicit, Size = 8)]
internal struct MyData
{
[FieldOffset(0)]
public short Level;
[FieldOffset(2)]
public int Weight;
[FieldOffset(6)]
public short Indicator;
}
Before you dive into use the AllocHGlobal method to grab some of that raw unmanaged memory that you want, be sure you have first prepared your code to let it go using the FreeHGlobal method. My preference is to do it by implementing IDisposable and a class destructor just in case I forget to dispose of my object that holds my precious unmanaged memory in its hands. Like this:
private bool disposed = false;
~MyPage()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
this.disposed = true;
if (this.myPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(this.myPtr);
this.myPtr = IntPtr.Zero;
}
}
}
Now you are ready to grab some memory and use it unsafely but responsibly with all the benefits that come from doing so. Here’s an example. Of course there are many more things you can do with unmanaged memory, but this will get you started.
public class MyPage : IDisposable
{
private IntPtr myPtr = IntPtr.Zero;
public MyPage(long capacity)
{
long size = Marshal.SizeOf(typeof(MyData));
long totalBytes = capacity * size;
this.myPtr = Marshal.AllocHGlobal(new IntPtr(totalBytes));
}
public MyData this[long index]
{
get
{
unsafe
{
return ((MyData*)this.myPtr.ToPointer())[index];
}
}
set
{
unsafe
{
((MyData*)this.myPtr.ToPointer())[index] = value;
}
}
}
private bool disposed = false;
~MyPage()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
this.disposed = true;
if (this.myPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(this.myPtr);
this.myPtr = IntPtr.Zero;
}
}
}
}
You will note that I have not included bounds checking in the above code, nor have I shown any code for initializing the data. Yes, this is living dangerously, but it is also one of the main reasons for using unsafe access to unmanaged memory—the performance advantage of not checking bounds. So drive safely. And if you are using unmanaged memory from C# for something clever or amazing, please tell us about it in comments.
I have said before that I like Uncle Bob's way with words. This includes his Clean Code Discussion:
"When aspects first came out, I was intrigued by the idea. But the more I learned, the less I liked it. The problem is that the pointcuts are tightly coupled to the naming and structure of the code. Simple name changes can break the pointcuts. This, of course, leads to rigidity and fragility. So, nowadays, I don't pay a lot of attention to AOP.
"For my money, the OO techniques that I demonstrated for logging can be pretty easily used for many other cross-cutting concerns. So the tight name-coupling of AOP isn't really necessary."
I too once thought that AOP was a great idea. A carefully crafted AOP solution can even overcome some of the coupling issues that Uncle Bob mentions. But eventually the dependency entanglements even with nice clean injection techniques, pick your poison, you end up with a hodge-podge of rigid and fragile. Eventually you find yourself writing code to serve your AOP solution rather than your use case.
My money is with Bob.