Introduction to generics in C# Part 6

Introduction

In the previous post we looked at constraints on generic type parameters using the ‘where’ keyword. We looked at an example where we wanted to limit the usage of an interface, IPropertiesPrinter, to those objects that implement another interface, namely IPrintable. We wanted to make sure that the generic type, i.e. the object to be printed, will have the GetProperties() method available. Without the constraint the generic object would only have the methods inherited from the Object class, such as ToString and GetHashCode.

In this post we’ll look at an example where not even constraints seem to provide a solution. I wanted to include this example in this series to show that sometimes not even generics can help create generic code.

A generic calculator

Imagine that we have some type of a calculator with a number of functions. The functions all require 2 input parameters and have a return value. The easiest operations to start with are the basic mathematical ones like here:

public class Calculator
{
	public int Add(int inputOne, int inputTwo)
	{
		return inputOne + inputTwo;
	}

	public int Divide(int inputOne, int inputTwo)
	{
		return inputOne / inputTwo;
	}

	public int Multiply(int inputOne, int inputTwo)
	{
		return inputOne * inputTwo;
	}

	public int Subtract(int inputOne, int inputTwo)
	{
		return inputOne - inputTwo;
	}
}

That’s fairly straightforward, right?

The problem is that this calculator is very “narrow-minded” in that it can only work with integers. Therefore you then add a second version to support doubles as well:

public class DoublesCalculator
{
	public double Add(double inputOne, double inputTwo)
	{
		return inputOne + inputTwo;
	}

	public double Divide(double inputOne, double inputTwo)
	{
		return inputOne / inputTwo;
	}

	public double Multiply(double inputOne, double inputTwo)
	{
		return inputOne * inputTwo;
	}

	public double Subtract(double inputOne, double inputTwo)
	{
		return inputOne - inputTwo;
	}
}

Later on you discover that there are other numeric types in .NET such as decimal, float and long so you’ll need to support them as well. Also, what about mixed calculators, where one input type is integer and the second is double? The number of calculator types will just keep on growing.

Luckily we have generics. Generic classes allow us to have multiple type parameters as we saw previously.

Let’s see how a generic Calculator could be implemented. It shouldn’t be too difficult, right? We’ll only look at addition as the rest will behave the same:

public class GenericCalculator<ReturnType, InputTypeOne, InputTypeTwo>
{
	public ReturnType Add(InputTypeOne firstParam, InputTypeTwo secondParam)
	{
		return (firstParam + secondParam) as ReturnType;
	}
}

The compiler will complain:

Operator ‘+’ cannot be applied to operands of type ‘InputTypeOne’ and ‘InputTypeTwo’

OK, luckily we now know about constraints so we should be able to limit the type parameters to numeric types only, right? Except that there’s no such constraint.

The following will fail:

public class GenericCalculator<ReturnType, InputTypeOne, InputTypeTwo> where ReturnType : Int32

…with the following error message:

‘int’ is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter.

Int32 is a struct, it cannot be used as a constraint. I’m obviously not the only one wondering about this case. There are many threads out there that inquire about this case:

So as of version 4.6.1 .NET doesn’t allow us to build generic classes and functions for numeric types only.

This was the last post in this series. I hope you’ve learnt something new.

View all various C# language feature related posts here.

Advertisements

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

iReadable { }

.NET Tips & Tricks

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: