Just wondering if there is a way to use LINQ in C++/CLI. I found one post that was focused on VS 2008 and required a bunch of workarounds for the System::String class. I hav
Are you talking about "Language Integrated Query" or the System::Linq
namespace? Every programmer I know prefers the function call syntax instead of LINQ syntax.
C++/CLI does not support LINQ syntax. Databases have supported a form of language integrated query in the past, called Embedded SQL, which is pretty much dead these days. Embedded SQL (and later LINQ-to-SQL) was a dumb idea to begin with, people have since figured out that database query logic should be in the database and not mixed into the business logic.
LINQ-to-objects is a more useful idea, but SQL syntax just feels out of place. So C# programmers tend to call the LINQ library functions directly.
C++ doesn't really need LINQ, because we have templates. The standard library algorithms made possible by templates are a superset of the advantages of LINQ: They can be specialized for particular containers, but you get a good default implementation without any help from the container class. And they compile to much more efficient code, because overload resolution happens after specialization (unlike generics). Ok, templates aren't as good for runtime reflection as generics, but C# extension methods don't play well with runtime reflection either. The biggest drawback of the C++ standard algorithms has been the verbosity of writing predicate functors, but C++0x introduces lambdas which take care of that.
Really what C++/CLI needs is a version of the standard algorithms that works on .NET containers. And here it is. For example, LINQ's Where
method corresponds pretty closely to find_if
. Now we just need Microsoft to hurry up and implement the final C++0x spec.
You can use the Linq methods that are defined in the System::Linq
namespace, but you'll have to jump through a couple extra hoops.
First, C++/CLI doesn't support extension methods. However, the extension methods are regular methods defined on various classes in System::Linq
, so you can call them directly.
List<int>^ list = gcnew List<int>();
int i = Enumerable::FirstOrDefault(list);
Second, C++/CLI doesn't support lambda expressions. The only workaround is to declare an actual method, and pass that as a delegate.
ref class Foo
{
public:
static bool GreaterThanZero(int i) { return i > 0; }
void Bar()
{
List<int>^ list = gcnew List<int>();
int i = Enumerable::FirstOrDefault(list, gcnew Func<int, bool>(&Foo::GreaterThanZero));
}
}