Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 返回接口时是否存在性能损失?_C#_Performance_Interface - Fatal编程技术网

C# 返回接口时是否存在性能损失?

C# 返回接口时是否存在性能损失?,c#,performance,interface,C#,Performance,Interface,考虑返回实现此接口的对象的接口和方法: interface ILoggedData { public int Id {get;} public string Description {get;} } class LoggedDataReader { public ILoggedData GetLoggedData() { ... LoggedData loggedData = new LoggedData(...);

考虑返回实现此接口的对象的接口和方法:

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属性”。我假设只返回对loggedData对象的引用,并将其解释为对接口的引用

这是正确的,还是从对象到接口的类型转换实际上起了什么作用

我假设从LoggedData到接口的转换没有任何作用。您可以将其视为编译的限制

问题就在这里。如果您认为使用接口是无用的,只会影响性能,那么为什么一开始就存在接口呢

接口的使用与否与性能关系不大,而与多态性的实现无关


在99.99999999999%的情况下,使用接口或具体类的决定不应基于性能原因。

这在很大程度上取决于您返回的接口类型。让我们看三个简单的例子:

  • 对象作为接口返回:最可能的可消除影响(如图所示)
  • 返回struct对象作为接口:出现装箱,这是一个常见的性能瓶颈()
  • 返回对象列表当接口:内存压力增加时,热路径上的性能可能会受到很大影响。详细解释
  • public IEnumerable GetLoggedData()
    {
    返回新列表(){new LoggedDataClass()};
    }
    
    答案是。。。 …是!在某些情况下,“类型转换”意味着不必要的副作用。另一个答案没有考虑C#编译器的内部工作。例如,这是不正确的:

    接口的使用与否与性能关系不大 所有关于多态性的实现

    接口的使用使得编译器更难,有时甚至不可能优化某些操作。最常见的陷阱是
    foreach
    关键字使用的
    GetEnumerator
    模式。对于强类型(例如
    列表
    ),编译器可以使用优化的枚举数,而对于弱类型(例如
    IList
    IEnumerable
    ),情况并非如此


    每个C#开发人员都应该了解这一点。

    在这种情况下,它什么也不做。您甚至可以在类之外的任何地方调用此代码,而不会出现任何错误:var description=new LoggedDataReader().GetLoggedData().description;对于值类型,它将导致装箱,否则不会产生影响。Related:也没有,开销在方法的调用程序中,访问接口成员。每个成员大约一纳秒,这是高度优化的。你有两匹马,你想知道哪匹马跑得更快。和他们赛跑!你已经用两种方式编写了代码,所以现在用两种方式运行它,运行得更快的就是运行得更快的。OP没有说使用接口是无用的——当他们说“编译的限制”时他们正在讨论通过使用一个忽略设置器的接口来限制对属性设置器的访问。这个答案99.99999999999%不准确。接口通常会带来巨大的损失。谢谢你的链接。这个答案对于原始海报中描述的常见情况是正确的,但第一点中的“无影响”取决于许多事情是否正常。NET中存在接口使用的“坏路径”,这会导致较小但可测量的性能损失;2010年,我们在为Roslyn设计基本数据结构时,在考虑OP的问题时测量了这些影响。不幸的是,我不是测量这些影响的人,因此我不熟悉细节,而且,在这十年中,CLR可能已经进行了优化。我对原始海报的建议将是我对所有性能问题的建议。进行经验测量。关于第一点,我想没有人会注意到:P。更新了一个更准确的陈述。
    public ILoggedData GetLoggedData() => new LoggedDataClass();
    
    public ILoggedData GetLoggedData() => new LoggedDataStruct();
    
    public IEnumerable<ILoggedData> GetLoggedData()
    {
        return new List<ILoggedData>() { new LoggedDataClass() };
    }