Implementing IEnumerable<T> in C++/CLI

by Brian Ensink 4. February 2010 22:02

Most of the .NET code I write is in C# but occasionally I need to write mixed mode C++/CLI code to expose some existing unmanaged code to our new .NET code.  C++/CLI works very well for this kind of interop but the language is much less familiar to me than C#. 

For example today I wanted to implement a property on a C++/CLI class that returned IEnumerable<T> to expose an unmanaged collection.  In C# this is a very easy with the yield keyword but there is no equivalent in C++/CLI so the enumerator classes have to implemented manually.  I got hung up on the syntax and it to took me far to many google searches before finally piecing it together.  So here is a complete but simple example implementation of IEnumerable<T> in C++/CLI.

You can download the full code here.

#pragma once
using namespace System;
namespace CppLibrary
{
public ref class Earth
{
private:
ref class EarthContinents : System::Collections::Generic::IEnumerable<String^>
{
private:
Earth^ _earth;

public:
EarthContinents(Earth^ Earth)
{
_earth = Earth;
}

virtual System::Collections::Generic::IEnumerator<String^>^ GetEnumerator_Generic() sealed
= System::Collections::Generic::IEnumerable<String^>::GetEnumerator
{
return gcnew EarthContinentsEnumerator(this);
}

virtual System::Collections::IEnumerator^ GetEnumerator_NonGeneric() sealed
= System::Collections::IEnumerable::GetEnumerator
{
return GetEnumerator_Generic();
}

private:
ref class EarthContinentsEnumerator : System::Collections::Generic::IEnumerator<String^>
{
private:
EarthContinents^ _continents;
int _index;

public:
EarthContinentsEnumerator(EarthContinents^ Continents)
{
_continents = Continents;
Reset();
}

~EarthContinentsEnumerator() { }

virtual bool MoveNext()
{
_index += 1;
return _index < _continents->_earth->_arr->Length;
}

property String^ Current_Generic
{
virtual String^ get() sealed
= System::Collections::Generic::IEnumerator<String^>::Current::get
{
return _continents->_earth->_arr[_index];
}
}

property Object^ Current_NonGeneric
{
virtual Object^ get() sealed
= System::Collections::IEnumerator::Current::get
{
return Current_Generic;
}
}

virtual void Reset()
{
_index = -1;
}
};
};

private:
array<String^>^ _arr;

public:
Earth()
{
_arr = gcnew array<String^>(7);
_arr[0] = gcnew String(L"Asia");
_arr[1] = gcnew String(L"Africa");
_arr[2] = gcnew String(L"North America");
_arr[3] = gcnew String(L"South America");
_arr[4] = gcnew String(L"Antarctica");
_arr[5] = gcnew String(L"Europe");
_arr[6] = gcnew String(L"Australia");
}

property System::Collections::Generic::IEnumerable<String^>^ Continents
{
System::Collections::Generic::IEnumerable<String^>^ get()
{
return gcnew EarthContinents(this);
}
}
};
}

Tags:

Software Development

Architecture via Prototyping?

by Brian Ensink 27. January 2010 21:42

Prototyping the architecture for a large new project can be a valuable step. It can help solidify high level software architecture, measure performance, simulate different scenarios, drive further discussion, and more.  But a prototype is a poor way to convey a proposed architecture and is no substitution for a real discussion about a specific project's architecture.  Implementing a prototype is time consuming and expensive and its easy to get caught up in technical details and lose sight of the purpose.  Consider prototyping a complex client-server application, for example a MMORPG.  Seems like multiple prototypes would be involved during the project but is there any doubt that the development team would start with pencil and paper or at a whiteboard and toss around out ideas?

The question is really simple: What architecture is being prototyped?  The "what" question can't be answered by the code of the prototype itself.  Rather the "what" is the architecture concept resulting from a real discussion before any prototype is implemented.  Without that discussion even the developer doing the prototype has a hard time answering the simple question: "What is being prototyped?".  And if that is the case it is time to take a step back and just talk about the architecture.

Tags:

Software Development

Silver Friday

by Brian Ensink 28. November 2009 14:15

Instead of Black Friday and shopping I had Silver Friday and spent part of the day looking at Silverlight 4 Betaannounced at PDC09.  Its always fun to look at new technology and this was the first time I have looked at any version of Silverlight.

I mostly focused on Silverlight’s potential to support cross-platform (MacOS and Windows) desktop applications because I may be able to use it in a future project.  Users can try a demo app online, install it locally and get more features when running out of the browser.  The app can also silently update itself with the latest version from the parent website keeping all clients on the same version.

Enabling out of browser support requires no code, just a couple build settings in project properties.  The user installs the app by following a right click menu of the app when running in a browser.  The out of browser app can be configured to run in trusted mode giving it access to parts of the local file system and a few other things.  The trusted app still runs in the Silverlight sandbox but the sandbox is a just little bigger.

I found one limitation that is a deal breaker for my upcoming project however.  The Silverlight 4 clipboard only supports text.  No images, no vector graphics, just text.  Regardless of these limitations Silverlight still has great potential to deliver cross platform desktop applications.

Tags:

Software Development

About the author

I am currently a .NET developer and really enjoy the platform.  .NET seems to be able to take the developer whereever he/she wants to go.  To the desktop, to the web, to a database, etc.  At my day job I write desktop apps but I also like to toy with other tech as I have time.