2

Consider an interface and a method that returns an object that implements this interface:

interface ILoggedData
{
    public int Id {get;}
    public string Description {get;}
}

class LoggedDataReader
{
    public ILoggedData GetLoggedData()
    {
        ...
        LoggedData loggedData = new LoggedData(...);
        return loggedData;
    }

    private class LoggedData : ILoggedData
    {
        ...
        public int Id {get; set;}
        public string Description {get; set;}
    }
}

So LoggedDataReader.GetLoggedData creates an object of private class LoggedData and returns the interface ILoggedData.

I assumed that the conversion from LoggedData to the interface doesn't do anything. You can regard it as a limitation for the compiler: "You can only use these getter properties". I assumed that just the reference to the loggedData object is returned, and interpreted as the reference to the interface.

Is this correct, or does the type conversion from object to interface actually do anything?

Harald Coppoolse
  • 28,834
  • 7
  • 67
  • 116
  • 1
    In this case it does nothing. You can even call this code anywhere you like outside this classes without any error: var description = new LoggedDataReader().GetLoggedData().Description; – Roman Ryzhiy Sep 01 '20 at 12:04
  • 2
    With value types it would cause boxing, otherwise there's no impact. – Johnathan Barclay Sep 01 '20 at 12:06
  • 3
    Related: [Performance of “direct” virtual call vs. interface call in C#](https://stackoverflow.com/questions/7225205/performance-of-direct-virtual-call-vs-interface-call-in-c-sharp) and also [Is it better performance wise to use the concrete type rather than the interface](https://stackoverflow.com/questions/4256928/is-it-better-performance-wise-to-use-the-concrete-type-rather-than-the-interface) – Theodor Zoulias Sep 01 '20 at 12:11
  • 4
    None, the overhead is in the caller of the method, accessing the interface members. About a nanosecond per member, it is highly optimized. Gritty details [are here](https://stackoverflow.com/a/42187448/17034). – Hans Passant Sep 01 '20 at 12:19
  • 2
    You have two horses and you wish to know which is the faster. Race them! You've written the code both ways, so now run it both ways, and the one that runs faster is the faster one. – Eric Lippert Sep 01 '20 at 20:59

2 Answers2

0

I assumed that the conversion from LoggedData to the interface doesn't do anything. You can regard it as a limitation for the compile

Well the problem is right there. If you think that using interfaces is useless and just hinders performance, then why are do interfaces exist to begin with?

The use or not of interfaces has very little to do with performance and all about implementation decoupling an polymorphism.

In 99.999999999999% of the situations the decision on using an interface or a concrete class should neverbe based upon performance reasons.

InBetween
  • 32,319
  • 3
  • 50
  • 90
  • 1
    The OP didn't say that using interfaces is useless - when they say "a limitation for the compile" they are talking about restricting access to the property setters by using an interface that omits the setters. – Matthew Watson Sep 01 '20 at 13:11
  • 1
    This answer is 99.999999999999% inaccurate. Interfaces often come with a tremendous penalty. – l33t Sep 01 '20 at 13:16
0

It very much depends on what type of interface you return. Let's look at three simple examples:

  1. Return class object as interface: Most likely neglible impact (as shown here)
public ILoggedData GetLoggedData() => new LoggedDataClass();
  1. Return struct object as interface: Boxing occurs, a common performance bottleneck (MSDN).
public ILoggedData GetLoggedData() => new LoggedDataStruct();
  1. Return list of objects as interface: Memory pressure increases, performance can suffer greatly on hot paths. Detailed explanation here.
public IEnumerable<ILoggedData> GetLoggedData()
{
    return new List<ILoggedData>() { new LoggedDataClass() };
}

The answer...

...is yes! In certain circumstances, the "type conversion" implies unwanted side-effects. The other answer does not take the inner workings of the C# compiler into consideration. E.g. this is incorrect:

The use or not of interfaces has very little to do with performance and all about implementation decoupling an polymorphism.

The use of interfaces makes it harder and sometimes impossible for the compiler to optimize certain operations. The most common pitfall is the GetEnumerator pattern used by the foreach keyword. With a strong type - e.g. List<T> - the compiler can use the optimized enumerator whereas the same is not true for a weak type - e.g. IList<T> or IEnumerable<T>.

Every C# developer should read Lippert's blog post about this.

l33t
  • 18,692
  • 16
  • 103
  • 180
  • 1
    Thanks for the link. This answer is correct for the common case described by the original poster, but that "no impact" in point one is conditional upon a number of things going right. There are "bad paths" for interface usage in .NET which lead to small but measurable performance penalties; we measured these when considering OP's question while designing the basic data structures for Roslyn back in 2010. – Eric Lippert Sep 01 '20 at 20:56
  • Unfortunately I was not the person who measured those impacts, so I am not conversant with the details, and moreover, there may have been optimizations in the CLR in the intervening decade. My advice to the original poster would be my advice for all performance questions. **Do empirical measurements**. See https://ericlippert.com/2012/12/17/performance-rant/ for my rant on the subject. – Eric Lippert Sep 01 '20 at 20:58
  • 1
    Regarding point one, I thought nobody would notice :P. Updated with a more accurate statement. – l33t Sep 01 '20 at 22:23