Performance in .NET – Part 3

Introduction

This post is part of a series on performance in .NET. See the first one on object instantiation and the second on property copying here. This time I’m going to talk about collections, but focusing on the performance side.

Collections

Back in 2009 (!) I wrote a blog post, which I updated a couple of times, about .NET collection types. Essentially, my point was – is – that you should pick the right collection for the job that you have at hands. This post is still up to date.

How many of us don’t by default just choose List<T> when there is need for a general-purpose collection? I certainly do, at times… Well, it turns out that this may or may not be what we need. Let me give a few examples.

List<T> is an array-based collection, which means that it is probably the best if you are going to iterate through items one at a time, sequentially, but it is not so good if you want to remove items from a random position other than the list’s end, because this causes a whole new array to be instantiated in memory, and all items (except the one that you wish to remove, of course) from the original list to be copied into the new one. It’s the same problem with random inserts at any given position, other than the end, and only if the initial capacity isn’t exceeded.

For operations where random inserts and deletes are required, LinkedList<T> is a much better choice as it does not require the instantiation of new arrays and the memory copy. It does that, however, at the expense of a slightly poorer performance in list traversal.

What about duplicates? With the previous list implementations, if we don’t want to allow duplicates, we need to check one by one, which is a PITA. Luckily, the .NET BCL has an implementation of a mathematical set which automatically excludes duplicates. One implementation is HashSet<T>, which is an indexed collection that uses each object’s GetHashCode method to figure out if the object already exists in the collection; needless to say, this method must be properly implemented.

Talking about indexed collections, if we want to be able to rapidly get to one element – or a number of elements – by some key, .NET has that as well: Dictionary<TKey, TValue> for storing a single value per unique key. The key can be of whatever type we want. This one also offers good performance when it comes to retrieving, adding, removing or modifying a single item.

Then we have LIFO and FIFO implementations in the form of the Stack<T> and Queue<T> types, which are optimized for adding items at the top or the bottom of the list, respectively, and don’t even allow other kinds of operations other than traversal. Internally they also use a linked-list approach.

Bits have their own specialized collections, BitArray and BitVector32. The latter only works with up to 32 bits and it probably provides the fastest performance of the two, according to Microsoft:

BitVector32 is more efficient than BitArray for Boolean values and small integers that are used internally. A BitArray can grow indefinitely as needed, but it has the memory and performance overhead that a class instance requires. In contrast, a BitVector32 uses only 32 bits.

Finally, Microsoft makes available thread-safe collections that are thread-safe in nature and therefore do not need any thread synchronization mechanisms, which makes them faster than if we had to roll out our own thread synchronization. They include thread-safe dictionaries (ConcurrentDictionary<TKey, TValue>), queues (ConcurrentQueue<T>), stacks (ConcurrentStack<T>) and general-purpose lists (BlockingCollection<T>).

Conclusion

I didn’t go through all the collection classes available, for that you can refer to my previous post.

The point I want to make with this post is:

  • Pick the right collection for the job; use the 80-20 rule and try to understand what the most common usage for your collection will be; do not just go blindly with List<T> or similar
  • Always expose collections publicly though interfaces or base classes that only show the bare minimum required, so that you can swap out the implementation should you need to
  • And, of course, measure your usage so that you can make opinionated decisions.

If performance is not an issue, by all means, forget about this and keep on doing what you are already doing and works for you.

Java vs C# – Part 3

Introduction

This is the third in a series of posts about the similarities and differences between C# (and .NET, to some extent) and Java. You can find the first one here and the second one here.

Again, with this I do not intent to demonstrate that one is superior to the other – totally – as I really like both platforms, even though I work mostly with C# and .NET. This is merely an exercise to show these differences and maybe it can be useful to someone who is learning one or the other. If you find something that you think is wrong, please let me know!

Keyword Usage

In Java, it is not possible to use reserved words, or keywords, such as class, public, etc, as variables, parameters or field names. In C# you can if you prefix it with @:. For example:

var @class = “My Class”;

Object Class

The Object class is the root of both type hierarchies in both Java and .NET. The two are pretty similar, with some remarkable exceptions. All of the following have exactly identical behavior:

Java .NET
clone MemberwiseClone
getClass GetType
equals Equals
hashCode GetHashCode
finalize Finalize
toString ToString

.NET does not offer methods corresponding to notify, notifyAll or wait. On the other hand, Java does not offer a method like ReferenceEquals.

Tuples

Recent versions of C# lets us return tuples, which are sets of values combined together ad hoc, but not inside a type definition. For example, should you wish to return a coordinate from a method, you could do this:

(double x, double y) GetCoordinates()

{

double x = …;

double y = …;

return (x, y);

}

It is also possible to “deconstruct” a class into a tuple, by providing a proper Deconstruct method:

public class Coordinate

{

public void Deconstruct(out double x, out double y)

{

x = …;

y = …;

}

}

Coordinate coord = …;

(double x, double y) = coord;

You can have as many Deconstruct methods you like, provided their signatures are different. For now, at least, Java is still lacking this functionality.

nameof

C# lets us use the nameof keyword to obtain a strongly-typed name of a class, method, property, field or parameter. It is very useful because it is refactor-friendly: should you change the name of the target, you also change the value that is being assigned. An example:

var className = nameof(MyClass); //”MyClass”

var fieldName = nameof(MyClass.MyField); //”MyField”

Mind you, only the “final” piece is returned, for example, if you use nameof with a fully qualified type name, you’ll only get the type name.

Friend Assemblies

As you know, internal classes and their methods are not available outside the current assembly/namespace. In C#/.NET, however, we can make these internals available to other assemblies by applying the InternalsVisibleToAttribute attribute to the assembly that we want to make available. These are called friend assemblies. For example:

[assembly:InternalsVisibleTo(“My.Assembly”)]

Async/Await

C# 5 introduced a new asynchronous programming model around the async and await keywords. I won’t go into the details of it but essentially it simplifies asynchronous programming a lot, preventing the usage of a lot of boilerplate code. It goes like this:

async Task<int> Compute(int a, int b) { … }

var result = await Compute(1, 2);

Import Methods

In C# we can import public static methods from public classes, which means, we can use them without prefacing them with the name of the class. The syntax is like this:

using static System.Environment;

and the usage:

var path = GetEnvironmentVariable(“PATH”);

Local Functions

.NET allows us to define local functions, that is, functions that exist only in the scope of methods. They are similar to lambda functions, with some remarkable differences, among which:

  • They can have attributes applied to its parameters
  • They can have ref, out and other kind of parameters
  • They can be asynchronous

An example:

void SomeMethod()

{

int sum(int a, int b) => a + b;

var x = sum(1, 2);

}

The closest that Java offers is anonymous classes, which are actually pretty cool, IMO.

Asserts

Java offers the assert keyword as part of the language, this has no equivalent in .NET. An assert evaluates a Boolean condition which, if not found to be true, throws an error:

assert speed < SPEED_OF_LIGHT;

Forgot to say, assertions can be disabled, which means, they are turned into no-ops.

Next Steps

I still have a couple of things to talk about, so be prepared for a future post!

As always, do let me know if you think I got anything wrong or you wish me to clarify something.

.NET Core Service Provider Gotchas and Less-Known Features

Introduction

In this post I’m going to talk about a few gotchas with the .NET Core’s built-in inversion of control (IoC) / service provider (SP)/dependency injection (DI) library. It is made available as the Microsoft.Extensions.DependencyInjection NuGet package.

I wrote another post some time ago, but this one supersedes it, in many ways.

Extension Methods

The single method exposed by the IServiceProvider interface, GetService, is not strongly typed. If you add a using statement for Microsoft.Extensions.DependencyInjection, you’ll get a few ones that are:

  • GetRequiredService<T>: tries to retrieve a service that is registered under the type of the generic template parameter and throws an exception if one cannot be found; if it is, it is cast to the template parameter;
  • GetService<T>: retrieves a service and casts it to the template parameter; if no service is found, null is returned;
  • GetServices<T>: returns all services registered as the template parameter type, cast appropriately.

Using a Different Service Provider

You are not forced to use the built-in service provider; you can use anyone you like, as long as it exposes an IServiceProvider implementation. You just need to return this implementation from the ConfigureServices method, which normally does not return anything:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
//return an implementation of IServiceProvider
}

Why would you want to do that, you may ask? Well, there are service providers out there that offer much more interesting features than Microsoft’s (for example, more lifetimes), and this has a reason: Microsoft kept his simple on purpose.

Multiple Registrations

You may not have realized that you can register any number of implementations for a given service, even with different lifetimes:

services.AddTransient<IService, ServiceA>();
services.AddScoped<IService, ServiceB>();

So, what happens when you ask for an implementation for IService? Well, you get the last one registered, in this case, ServiceB. However, you can ask for all the implementations, if you call GetServices<T>.

Registration Factories

You can specify how a service implementation is constructed when you register a service, and it can depend upon other services that are also registered in the service provider:

services.AddTransient<IService>(sp => new ServiceImpl(sp.GetRequiredService<IOtherService>));

Don’t worry about registration order: IOtherService will only be required once IService is retrieved.

Lifetime Dependencies

You cannot have a Singleton registration depend upon a Scoped service. This makes sense, if you think about it, as a singleton has a much longer lifetime than a scoped service.

Nested Scopes

You can create nested scopes at any time and retrieve services from them. If you are using the extension methods in the Microsoft.Extensions.DependencyInjection namespace, it’s as easy as this:

using (var scope = serviceProvider.CreateScope())
{
    var svc = scope.ServiceProvider.GetRequiredService<IService>();
}

The CreateScope method comes from the IServiceScopeFactory implementation that is registered automatically by the dependency injection implementation. See next for implications of this.

Why is this needed? Because of lifetime dependencies: using this approach you can instantiate a service marked as a singleton that takes as a parameter a scoped one, inside a scope.

Dispose Pattern

All services instantiated using the Scoped or Transient lifetimes that implement the IDisposable interface will have their Dispose methods called at the end of the request – or the nested scope (when it is disposed). The root service provider is only disposed with the app itself.

Scope Validation

The built-in service provider validates the registrations so that a singleton does not depend on a scoped registration. This has the effect of preventing retrieving services in the Configure method, through IApplicationBuilder.ApplicationServices, that are not transient or singletons.

If, however, you think you know what you’re doing, you can bypass this validation:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
//add services
return services.BuildServiceProvider(validateScopes: false);
}

As I said before, the other alternative is creating a scope and instantiating your singleton service inside the scope. This will always work.

Injecting Services

ASP.NET Core only supports constructor:

public HomeController(IService svc)
{
}

and parameter:

public IActionResult Index([FromServices] IService svc)
{
}

inheritance, but not property, in controllers and Razor Pages. You can achieve that through actions or conventions. Another option is to use the Service Locator pattern.

Service Locator

You can retrieve any registered services from HttpContext.RequestServices, so whenever you have a reference to an HttpContext, you’re good. From the Configure method, you can also retrieve services from IApplicationBuilder.ApplicationServices, but not scoped ones (read the previous topics). However, it is generally accepted that you should prefer constructor or parameter injection over the Service Locator approach.

Conclusion

Although the service provider that comes with .NET Core is OK for most scenarios, it is clearly insufficient for a number of others. These include:

  • Other lifetimes, such as, per resolve-context, per thread, etc;
  • Property injection;
  • Lazy<T> support;
  • Named registrations;
  • Automatic discovery and configuration of services;
  • Child containers.

You should consider a more featured DI library, and there are many out there, if you need any of these.

Integrating Managed Extensibility Framework with the .NET Service Provider

Introduction

It seems I’m in the mood for Managed Extensibility Framework: second post in a week about it! This time, I’m going to talk about how we can integrate it with the .NET Core’s service provider/dependency injection (DI) library (Microsoft.Extensions.DependencyInjection).

Mind you, this will apply to both ASP.NET Core and .NET Core console apps.

Locating Services

We’ve seen before how we can find all types that match a given interface:

public static class ContainerConfigurationExtensions     {         public static ContainerConfiguration WithAssembliesInPath(this ContainerConfiguration configuration, string path, SearchOption searchOption = SearchOption.TopDirectoryOnly)         {             return WithAssembliesInPath(configuration, path, null, searchOption);         }         public static ContainerConfiguration WithAssembliesInPath(this ContainerConfiguration configuration, string path, AttributedModelProvider conventions, SearchOption searchOption = SearchOption.TopDirectoryOnly)         {             var assemblyFiles = Directory                 .GetFiles(path, "*.dll", searchOption);             var assemblies = assemblyFiles                 .Select(AssemblyLoadContext.Default.LoadFromAssemblyPath);             configuration = configuration.WithAssemblies(assemblies, conventions);             return configuration;         }     }

Service Registration

The next step is picking up all of the found types and registering them with the DI:

public static class ServiceCollectionExtensions     {         public static IServiceCollection AddFromAssembliesInPath<T>(this IServiceCollection services, ServiceLifetime lifetime, string path = null) where T : class         {             var factory = new ExportFactory<T, object>(() => new Tuple<T, Action>(Activator.CreateInstance<T>(), () => { }), new object());             var conventions = new ConventionBuilder();             var builder = conventions                 .ForTypesDerivedFrom<T>()                 .Export<T>();             if (lifetime == ServiceLifetime.Singleton)             {                 builder = builder.Shared();             }             path = path ?? AppContext.BaseDirectory;             var configuration = new ContainerConfiguration()                 .WithAssembliesInPath(path, conventions);             using (var container = configuration.CreateContainer())             {                 var svcs = container.GetExports<Lazy<T>>();                 foreach (var svc in svcs)                 {                     services.Add(new ServiceDescriptor(typeof(T), sp => svc.Value, lifetime));                 }             }             return services;         }         public static IServiceCollection AddSingletonFromAssembliesInPath<T>(this IServiceCollection services, string path = null) where T : class         {             return AddFromAssembliesInPath<T>(services, ServiceLifetime.Singleton, path);         }         public static IServiceCollection AddScopedFromAssembliesInPath<T>(this IServiceCollection services, string path = null) where T : class         {             return AddFromAssembliesInPath<T>(services, ServiceLifetime.Scoped, path);         }         public static IServiceCollection AddTransientFromAssembliesInPath<T>(this IServiceCollection services, string path = null) where T : class         {             return AddFromAssembliesInPath<T>(services, ServiceLifetime.Transient, path);         }     }

The AddFromAssembliesInPath extension method is what does all the work; it leverages the previous WithAssembliesInPath method to locate all types that match a given interface, in the assemblies inside a specific folder (which can be the current one). AddSingletonFromAssembliesInPath, AddScopedFromAssembliesInPath and AddTransientFromAssembliesInPath are merely here to make your life a (little bit) easier. Although MEF only supports singletons (Shared) and transient (Non-shared) lifetimes, with this approach

Notice how MEF let’s us resolve Lazy<T> instances besides T. This is pretty cool, as we can delay object instantiation to a later stage, when the object is actually needed. A word of caution: the instantiation will actually be done by MEF, not by the .NET Core DI, so you won’t have constructor injection.

Putting it all Together

So, armed with these two extension methods, we can add this to the ConfigureServices method of your ASP.NET Core app (or wherever you populate your service provider):

services.AddTransientFromAssembliesInPath<IPlugin>();

Here IPlugin is just some interface, nothing to do with the one described in the previous post. After this, you should be able to inject all of the actual implementations:

public class HomeController : Controller

{

public HomeController(IEnumerable<IPlugin> plugins) { … }

}

Dynamically Loading Middleware in ASP.NET Core

Introduction

The concept of middleware has been around since ASP.NET MVC (pre-Core) and OWIN. Essentially, a middleware component lives in a pipeline and handles requests and acts as a chain of responsibility, delegating to any subsequent middleware components registered in the pipeline after itself. The following image (taken from the Microsoft site) shows this.

Image result for asp.net core middleware

MVC itself is implemented as a middleware component, as is redirection, exception handling, buffering, etc.

A middleware component can be added in several ways, but in ASP.NET Core, it all goes down to the Use method in IApplicationBuilder. Lots of API-specific methods rely on it to add their own middleware.

For the time being, we’ll make use of the IMiddleware interface that comes with ASP.NET Core. It provides a simple contract that has no dependencies other than the common HTTP abstractions.

One common request is the ability to load and inject middleware components dynamically into the pipeline. Let’s see how we can

Managed Extensibility Framework

.NET Core has Managed Extensibility Framework (MEF), and I previously blogged about it. MEF offers an API that can be used to find and instantiate plugins from assemblies, which makes it an interesting candidate for the discovery and instantiation of such middleware components.

Image result for managed extensibility frameworkWe’ll use the System.Composition NuGet package. As in my previous post, we’ll iterate through all the assemblies in a given path (normally, the ASP.NET Core’s bin folder) and try to find all implementations of our target interface. After that we’ll register them all to the MEF configuration.

Implementation

Our target interface will be called IPlugin and it actually inherits from IMiddleware. If we so wish, we can add more members to it, for now, it really doesn’t matter:

public interface IPlugin : IMiddleware
{
}

The IMiddleware offers an InvokeAsync method that can be called asynchronously and takes the current context and a pointer to the next delegate (or middleware component).

I wrote the following extension method for IApplicationBuilder:

public static class ApplicationBuilderExtensions

{

public static IApplicationBuilder UsePlugins(this IApplicationBuilder app, string path = null)        {

     var conventions = new ConventionBuilder();

        conventions

           .ForTypesDerivedFrom<IPlugin>()

           .Export<IPlugin>()

           .Shared();

           path = path ?? AppContext.BaseDirectory;

            var configuration = new ContainerConfiguration()

            .WithAssembliesInPath(path, conventions);

            using (var container = configuration.CreateContainer())

            {

           var plugins = container

                .GetExports<IPlugin>()

                    .OrderBy(p => p.GetType().GetCustomAttributes<ExportMetadataAttribute>(true)

.SingleOrDefault(x => x.Name == “Order”)?.Value as IComparable ?? int.MaxValue); 

               foreach (var plugin in plugins)

                {

                    app.Use(async (ctx, next) =>

                    {

                    await plugin.InvokeAsync(ctx, null);

                        await next();

                    });

                }

          }

          return app;

    }

}

We define a convention that for each type found that implements IPlugin we register it as shared, meaning, as a singleton.

As you can see, if the path parameter is not supplied, it will default to AppContext.BaseDirectory.

We can add to the plugin/middleware implementation an ExportMetadataAttribute with an Order value to specify the order by which our plugins will be loaded, more on this in a moment.

The WithAssembliesInPath extension method comes from my previous post but I’ll add it here for your convenience:

public static class ContainerConfigurationExtensions
{     public static ContainerConfiguration WithAssembliesInPath(this ContainerConfiguration configuration, string path, SearchOption searchOption = SearchOption.TopDirectoryOnly)     {      return WithAssembliesInPath(configuration, path, null, searchOption);     }     public static ContainerConfiguration WithAssembliesInPath(this ContainerConfiguration configuration, string path, AttributedModelProvider conventions, SearchOption searchOption = SearchOption.TopDirectoryOnly)     {         var assemblyFiles = Directory          .GetFiles(path, "*.dll", searchOption);         var assemblies = assemblyFiles             .Select(AssemblyLoadContext.Default.LoadFromAssemblyPath);         configuration = configuration.WithAssemblies(assemblies, conventions);         return configuration;     }
}

If you want to search all assemblies in nested directories, you need to pass SearchOption.AllDirectories as the searchOption parameter, but this, of course, will have a performance penalty if you have a deep directory structure.

Putting it All Together

So, let’s write a few classes that implement the IPlugin interface and therefore are suitable to be used as middleware components:

[Export(typeof(IPlugin))] [ExportMetadata(“Order”, 1)] public class MyPlugin1 : IPlugin {     public async Task InvokeAsync(HttpContext context, RequestDelegate next)     {         //do something here

//this is needed because this can be the last middleware in the pipeline (next = null)         if (next != null)         {             await next(context);         }

//do something here     } }

Notice how we applied an ExportMetadataAttribute to the class with an Order value; this is not needed and if not supplied, it will default to the highest integer (int.MaxValue), which means it will load after all other plugins. These classes need to be public and have a public parameterless constructor. You can retrieve any registered services from the HttpContext’s RequestServices property.

Now, all we need to do is add a couple of assemblies to the web application’s bin path (or some other path that is passed to UsePlugins) and call this extension method inside Configure:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

{

//rest goes here

app.UsePlugins(/*path: “some path”*/);

//rest goes here

}

And here you have it: ASP.NET Core will find middleware from any assemblies that it can find on the given path.

Hope you find this useful! Winking smile

Performance in .NET – Part 2

Introduction

This is the second in a series of posts about performance in the .NET ecosystem. On the first post, that you can find here, I talked about object instantiation. This time, it’s object cloning.

Object Cloning

You should be aware that there are two types of cloning:

  • Deep cloning: clones the root object and each reference its properties points to
  • Shallow cloning: clones the root object but each reference any of its properties points to is kept, that is, is also pointed to, not cloned

Microsoft defines one interface, ICloneable, which is implemented by a couple of classes, but doesn’t really say much about the type of cloning that it does. In fact, Microsoft actually advises against using it.

Sometimes we definitely need to make a copy of an existing object. This includes creating a new instance and then populating it with the values (or copies of) for the properties of the initial class. We have a few options:

  • Using the built-in MemberwiseClone method
  • Implementing our own cloning strategy
  • Using an object-to-object mapper
  • Serializing and deserializing

Memberwise Shallow Clone

The Object class defines a MemberwiseClone method that the documentation describes as doing a shallow copy of the current object. Because this is defined for Object, all classes inherit it, and it will make a copy of all fields declared along the class hierarchy. But, alas, being generic also means that it is not particularly suited for any concrete scenario. It uses it uses FormatterServices.GetUninitializedObject to create a “blank” instance of your class and then reflection to iterate through all of the instance fields of your class and makes a bitwise copy of them. Because of the reflection part, it’s probably not the fastest solution.

Custom Clone

Here you need to decide if you’re going for a shallow or a deep strategy, and depending on that, things can be more or less complicated. In general, a shallow copy is faster and simpler to implement as we know exactly what properties to copy, and you can even go for a shallow or a deep copy. An option is to use an object mapper.

Using a Mapper

Using a mapper such as Automapper can prove very useful as it can do lots of things out-of-the-box for you and still leave you space to handle any more complex situations. There are many out there, but Automapper is probably the most popular but there are alternatives:

So, the idea is, you construct the target instance (the copy) yourself and then you use the mapper to copy from the current instance into it. A decent mapper can use conventions to copy without requiring any configuration, but it will still require some reflection magic.

Serializing and Deserializing

This one, like using a mapper, also requires a third-party library. There are plenty out there, even included in the .NET framework, that can do this. This may seem like an overkill if you’re just trying to get a clone of your current object, but it works, and it is usually one of the easiest ways to get a deep copy. This is usually used for transmitting an object’s state over the wire, in any format that can be binary or text-based, and it can go back as well, translating this state back into a class. Usually also not the fastest approach, especially for complex object graphs.

Conclusion

Performance-wise, you’re probably better off by rolling out your cloning method, which will probably be unique for each class. This avoids reflection and serialization (which also uses reflection). Just make it clear to everyone that you’re implementing a shallow or a deep copy.

Performance in .NET – Part 1

Updated: thanks, Paulo Morgado!

Introduction

Along the years I wrote a couple of posts about performance in the .NET world. Some were more tied to specific frameworks, such as NHibernate or Entity Framework, while others focus on the generic bits. In this series of posts I will summarize my findings on .NET in general, namely:

  • Object creation (this post)
  • Object cloning
  • Value Types versus Reference Types
  • Collections
  • Possibly other stuff

I won’t be talking about object serialization, as there are lots of serializers out there, each with its pros and cons. In general, I’d say either serializing to and from JSON or from a binary format seem to be the most demanded ones, and each has quite a few options, either provided by Microsoft or from third parties. The actual usage also affects what we want – is it a general-purpose serializer or one for a particular usage, that needs classes prepared accordingly? Let’s keep it out of this discussion.

As always, feel free to reach out to me if you want to discuss any of these! So, lets start with object creation.

Object Creation

Let’s start with object creation and by defining our purpose: we want to be able to create object instances of a certain type as fast as possible. We have a couple of strategies:

Let’s cover them all one by one.

Using the new Operator

This is the most obvious (and fast), but does not play well with dynamic instantiation, meaning, the type to instantiate needs to be hardcoded. I call it direct instantiation, and it goes as this (you know, you know…):

var obj = new Xpto();

This should be the baseline for all performance operations, as it should offer the best possible performance.

Using Reflection

Here I’m caching the public parameterless constructor and invoking it, then casting the result to the target type:

var ci = typeof(Xpto).GetConstructor(Type.EmptyTypes);<br />var obj = ci.Invoke(null) as Xpto;

Just avoid getting the constructor over and over again, do it once for each type then cache it somewhere.

Using FormatterServices.GetUninitializedObject

The GetUninitializedObject method is used internally by some serializers and what it does is, it merely allocates memory for the target type and zeroes all of its fields, without actually running any constructor. This has the effect that any explicitly declared field and property values will be lost, so use with care. It is available in .NET Core:

var obj = FormatterServices.GetUninitializedObject(typeof(Xpto)) as Xpto;

Pay attention that none of the constructors of your type are executed, and no fields or properties have their initial values set, other than the default value for each type (null for reference types, the default for value types).

Using System.Reflection.Emit code generation

This one uses the code generation library that is built-in with .NET (but not .NET Core, for the time being):

var m = new DynamicMethod(string.Empty, typeof(object), null, typeof(Xpto), true);<br />var ci = typeof(Xpto).GetConstructor(Type.EmptyTypes);<br />var il = m.GetILGenerator();<br />il.Emit(OpCodes.Newobj, ci);<br />il.Emit(OpCodes.Ret);<br />var creator = m.CreateDelegate(typeof(Func<object>)) as Func<object>;<br />var obj = creator() as Xpto;

As you can see, we are just generating code for a dynamic method, providing a simple content that does “new Xpto()”, and execute it.

Using Activator.CreateInstance

This is essentially a wrapper around the reflection code I’ve shown earlier, with the drawback that it does not cache each types’ public parameterless constructor:

var obj = Activator.CreateInstance(typeof(Xpto)) as Xpto;

Using LINQ expressions

The major drawback of this approach is the time it takes to build the actual code (the first call to Compile). After that, it should be fast:

var ci = typeof(Xpto).GetConstructor(Type.EmptyTypes);<br />var expr = Expression.New(ci);<br />var del = Expression.Lambda(expr).Compile();<br />var obj = del.DynamicInvoke() as Xpto;

Of course, if you are to call this a number of times for the same type, it may be worth caching the constructor for each type.

Using Delegates

The LINQ expressions approach actually compiles to this one, but this is strongly typed:

Func<Xpto> del = () => new Xpto();<br />var obj = del();

Using Roslyn

This one is relatively new in .NET. As you may know, Microsoft now uses Roslyn to both parse and generate code dynamically. The scripting capabilities are made available through the Microsoft.CodeAnalysis.CSharp.Scripting NuGet package. The actual code for instantiating a class (or actually executing any code) dynamically goes like this:

var obj = CSharpScript.EvaluateAsync("new Xpto()").GetAwaiter().GetResult() as Xpto;

Do keep in mind that Roslyn is asynchronous by nature, so you need to wait for the result, also, do add the full namespace of your type, which I omitted for brevity. There are other APIs that allow you to compile code and reuse the compilation:

var script = CSharpScript.Create<Xpto>("new Xpto()", ScriptOptions.Default.AddReferences(typeof(Xpto).Assembly));<br />var runner = script.CreateDelegate();<br />var obj = runner().GetAwaiter().GetResult();

Conclusion

Feel free to run your tests, with a few iterations, and look at the results. Always compare with the normal way to create objects, the new operator. Do not forget the problems with each approach, like the need to cache something or any limitations on the instantiated object.

In my machine, for 1000 iterations, a couple times for the same run, I get these average results (elapsed ticks):

Technique Delay
Direct 0.148
FormatterServices.GetUninitializedObject 0.324
Activator.CreateInstance 0.296
Reflection 0.6
IL 0.557
LINQ Expression 4.085
Delegate 0.109
Roslyn 2400.796

Some of these may be surprising to you, as they were to me! It seems that reflection is not that much slower than direct instantiation as one might think… hmmm…

As usual, I’d love to hear your thoughts on this! More to come soon! Winking smile

C# Special Method Names

Introduction

You may not have realized that some of the patterns that you’ve been using for ages in your C# programs are based on conventions, rather than on a specific API. What I mean by this is, some constructs in C# are based on some magical methods with well-defined names which are not defined in any base class or interface, but yet just work. Let’s see what they are.

Enumerations

You are probably used to iterating through collections using the foreach statement. If you are, you may know that foreach actually wraps a call to a method called GetEnumerator, like the one that is defined by the IEnumerable and IEnumerable<T> interfaces. Thus, you might think, the magic occurs because the collection implements one or the two, but you would be wrong: it turns out that in order to iterate through a class using foreach all it takes is that the class exposes a public method called GetEnumerator that returns either a IEnumerator or a IEnumerator<T> instance. For example, this works:

public class Enumerable
{
    public IEnumerator GetEnumerator()
    {
        yield return 1;
        yield return 2;
        yield return 3;
    }
}

var e = new Enumerable();

foreach (int i in e) { /*...*/ }

As you see, there is no need to implement any of these interfaces, but it is a good practice, for example, because it gives you access to LINQ extension methods.

Deconstruction to Tuples

Tuples were introduce in C# 7. In a nutshell, they provide a way for us to return multiple values from a method:

(int x, int y) GetPosition()
{
    return (x: 10, y: 20);
}

Another option is to have a class deconstructed into a tuple. Say, for example, that we have a class like this:

public class Rectangle
{
    public int Height { get; set; }
    public int Width { get; set; }
}

We can have it deconstructed into a tuple, by providing one or more Deconstruct methods in this class:

public void Deconstruct(out int h, out int w)
{
    h = this.Height;
    w = this.Width;
}

Which allows you to write code like this:

var rectangle = new Rectangle { Height = 10, Width = 20 };
var (h, w) = rectangle;

You can implement multiple Deconstruct methods with different parameters, which must always be out. When you try to assign your class to a tuple, C# will try to find a Deconstruct method that matches the tuple’s declaration, or throw an exception if one cannot be found:

public void Deconstruct(out int perimeter, out int area, out bool square)
{
    perimeter = this.Width * 2 + this.Height * 2;
    area = this.Width * this.Height;
    square = this.Width == this.Height;
}

var (perimeter, area, square) = rectangle;

Collection Initialization

Since C# 6, we have a more concise syntax for initializing collections:

var strings = new List<string> { "A", "B", "C" };

The syntax to follow is an enumeration of items whose type matches the collection’s item type, inside curly braces, each separated by a comma. This is possible because there is a public Add method that takes a parameter of the appropriate type. What happens behind the scene is that the Add method is called multiple times, one for each item inside the curly braces. Meaning, this works too:

public class Collection : IEnumerable
{
    public IEnumerator GetEnumerator() => /* ... */
    public void Add(string s) { /* ... */ }
}

Notice that this collection offers a public Add method and needs to implement either IEnumerable or IEnumerable<T>, which, mind you, do not define an Add method. Having this, we can write:

var col = new Collection { "A", "B", "C" };

The magical Add method can have multiple parameters, like for dictionaries:

var dict = new Dictionary<string, int> { { "A", 1 }, { "B", 2 }, { "C", 3 } };

Each parameter will need to go inside it’s own set of curly braces.

What’s even funnier is, you can mix different Add methods with different parameters:

public void Add(int i) { /* ... */ }
public void Add(string s) { /* ... */ }

var col = new Collection { 1, 2, 3, "a", "b", "c" };

Conclusion

In this post I introduced the magical GetEnumerator, Deconstruct and Add methods. This was just for fun, the information here is probably useless, but, hey, it’s done! Winking smile

Succinctly Books Index

This page lists all the books I wrote or reviewed for Syncfusion’s Succinctly series.

Books I wrote:

Books I reviewed:

Stackify Posts Index

As some of you may remember, last year I started writing occasionally a few posts for Stackify (@Stackify). In this page I will try to keep this list updated.

Stay tuned for more!