如何解决返回接口时会降低性能吗?
考虑一个接口和一个返回实现此接口的对象的方法:
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;}
}
}
因此LoggedDataReader.GetLoggedData
创建一个私有类LoggedData
的对象并返回接口ILoggedData
。
我假设从LoggedData到接口的转换没有任何作用。您可以将其视为对编译器的限制:“您只能使用这些getter属性”。我假定只返回对loggingData对象的引用,并将其解释为对接口的引用。
这是正确的吗,还是从对象到接口的类型转换实际上有什么作用?
解决方法
我假设从LoggedData到接口的转换没有任何作用。您可以将其视为编译的限制
问题就在那里。如果您认为使用接口是无用的并且仅会影响性能,那么为什么存在接口才开始呢?
接口的使用与否与性能和实现与多态性的解耦关系不大。
在99.999999999999%的情况下,决不要基于性能原因决定使用接口或具体类。
,这在很大程度上取决于您返回的接口类型。让我们看三个简单的例子:
- 返回类对象作为界面:最有可能造成的疏忽影响(如here所示)
public ILoggedData GetLoggedData() => new LoggedDataClass();
- 返回 struct 对象作为接口:发生装箱,这是常见的性能瓶颈(MSDN)。
public ILoggedData GetLoggedData() => new LoggedDataStruct();
- 返回对象列表作为界面:内存压力增加,在热路径上性能可能会受到很大影响。详细说明here。
public IEnumerable<ILoggedData> GetLoggedData()
{
return new List<ILoggedData>() { new LoggedDataClass() };
}
答案...
... 是!在某些情况下,“类型转换”意味着不希望的副作用。另一个答案没有考虑C#编译器的内部工作原理。例如。这是不正确:
接口的使用与否与性能几乎没有关系 以及有关实现解耦多态性的一切。
接口的使用使编译器更难于优化某些操作,有时甚至是不可能的。最常见的陷阱是GetEnumerator
关键字使用的foreach
模式。具有强类型-例如List<T>
-编译器可以使用优化的枚举器,而对于弱类型则不是这样-例如IList<T>
或IEnumerable<T>
。
每个C#开发人员都应该阅读Lippert's blog post。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。