标签: default-interface-member

C#8中的默认接口方法

请考虑以下代码示例:

public interface IPlayer
{
  int Attack(int amount);
}

public interface IPowerPlayer: IPlayer
{
  int IPlayer.Attack(int amount)
  {
    return amount + 50;
  }
}

public interface ILimitedPlayer: IPlayer
{
  new int Attack(int amount)
  {
    return amount + 10;
  }
}

public class Player : IPowerPlayer, ILimitedPlayer
{
}
Run Code Online (Sandbox Code Playgroud)

我的问题在于代码:

IPlayer player = new Player();
Console.WriteLine(player.Attack(5)); // Output 55, --> im not sure from this output. I can compile the code but not execute it!

IPowerPlayer powerPlayer = new Player();
Console.WriteLine(powerPlayer.Attack(5)); …
Run Code Online (Sandbox Code Playgroud)

c# c#-8.0 default-interface-member

9
推荐指数
1
解决办法
703
查看次数

使用接口的委托作为参数类型时,逆变无效

考虑带有委托的逆变接口定义:

public interface IInterface<in TInput>
{
    delegate int Foo(int x);
    
    void Bar(TInput input);
    
    void Baz(TInput input, Foo foo);
}
Run Code Online (Sandbox Code Playgroud)

Baz失败的定义出现错误:

CS1961
无效方差:类型参数“ TInput”必须在“ IInterface<TInput>.Baz(TInput, IInterface<TInput>.Foo)”上协变有效。' TInput' 是逆变的。

我的问题是为什么?乍一看,这应该是有效的,因为Foo委托与TInput. 我不知道是编译器过于保守还是我遗漏了什么。

请注意,通常您不会在接口内声明委托,特别是这不会在早于 C# 8 的版本上编译,因为接口中的委托需要默认接口​​实现。

如果允许这个定义,有没有办法打破类型系统,或者编译器是否保守?

c# generics covariance contravariance default-interface-member

9
推荐指数
1
解决办法
251
查看次数

C#-8 接口中的抽象、虚拟和密封方法

使用C#-8.0的.Net Core Console应用程序中以下界面没有错误

interface I
{
    public abstract void f();
    public virtual void g() => Console.WriteLine("g");
    public sealed void h() => Console.WriteLine("h");
}
Run Code Online (Sandbox Code Playgroud)

abstract防止在接口中添加定义。virtual并且sealed需要在接口中进行定义。sealed阻止派生类中的实现h

abstract在接口中使用、virtualsealed时,在当前实现的 C# - 8 版本中还有其他含义或应用吗?它们应该如何以及何时在界面中使用?

c# c#-8.0 default-interface-member

7
推荐指数
1
解决办法
556
查看次数

我们什么时候应该在 C# 中使用默认接口方法?

C# 8及更高版本中,我们有默认的接口方法,因此:

不是破坏了接口的原理吗?

我们什么时候应该使用默认接口方法而不是基(抽象)类

c# interface c#-8.0 default-interface-member

7
推荐指数
2
解决办法
958
查看次数

如果在C#8.0中实现了默认接口方法,为什么我还需要抽象类?

我最近遇到了要考虑在下一版本的C#中添加的功能列表。其中之一称为“默认接口方法”:

https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md

简而言之,它将允许您在接口本身上定义实际的方法实现,这意味着接口现在可以具有实现。既然是这种情况,并且C#类可以从多个接口实现/继承,那么为什么我在世界上总是使用抽象类?

我唯一想到的是接口不能具有构造函数,因此可能需要在抽象类构造函数中运行一些逻辑,这将有理由定义一个抽象类。

还有其他人能想到的方案吗?

c# c#-8.0 default-interface-member

6
推荐指数
1
解决办法
1744
查看次数

从实现类调用C#接口默认方法

C#8支持接口中的默认方法实现。我的想法是将一个日志记录方法注入这样的类中:

public interface ILoggable {
    void Log(string message) => DoSomethingWith(message);
}

public class MyClass : ILoggable {
    void MyMethod() {
        Log("Using injected logging"); // COMPILER ERROR
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到一个编译器错误:“名称在当前上下文中不存在”

以这种方式使用默认方法实现是不可能的吗?

编辑:

有关C#规则的正确答案,请参见接受的答案。有关更简洁的解决方案(我的问题的初衷!),请参阅下面的答案

c# c#-8.0 default-interface-member

6
推荐指数
4
解决办法
400
查看次数

具有默认实现的接口和抽象类有什么区别?

C# 8.0 引入了一个新的语言特性——接口成员的默认实现。

public interface IRobot
{
    void Talk(string message)
    {
        Debug.WriteLine(message);
    }
}
Run Code Online (Sandbox Code Playgroud)

新的默认接口实现提供了特性语言的元素。然而,这也模糊了抽象类和接口之间的界限。

现在使用抽象类而不是具有默认实现的接口有什么好处?

c# oop abstract-class c#-8.0 default-interface-member

6
推荐指数
1
解决办法
1386
查看次数

使用 C#8 默认接口实现/特征的事件继承

目前,关于新 C#8 默认接口实现(特征)的事件限制的文档很少。我对规范提案特别困惑。该示例不仅给出了无效的 C#(“覆盖”事件缺少标识符),而且在 C#8(VS2019、.NET Core 3.0)中实现其中任何一个都会返回大量编译器异常。此外,C#8 的发行说明没有提及任何接口特征的事件。当我继续尝试寻找答案时,我也无法从开放问题列表中收集到任何有用的信息。

那么问题来了:这个功能是否实现并可用?如果是这样,正确的语法是什么?

c# .net-core c#-8.0 default-interface-member

6
推荐指数
1
解决办法
1126
查看次数

C# 默认接口实现 - 无法覆盖

我按照本指南https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods来使用默认接口实现功能。我复制了一段代码,该代码在接口中定义了默认实现IA,然后在接口中覆盖它IB

interface I0
{
    void M() { Console.WriteLine("I0"); }
}

interface I1 : I0
{
    override void M() { Console.WriteLine("I1"); }
}
Run Code Online (Sandbox Code Playgroud)

但它给出了一个错误CS0106 The modifier 'override' is not valid for this item和一个警告CS0108 'I1.M()' hides inherited member 'I0.M()'. Use the new keyword if hiding was intendedTargetFramework设置为net5.0LangVersionlatest。为什么即使官方文档中描述了它也不起作用?

c# default-interface-member

6
推荐指数
1
解决办法
4190
查看次数

为什么我的 C# 默认接口实现在具体类定义中未被识别?

我在 Visual Studio 2019 中有一个 .Net 6.0 应用程序。我正在尝试让默认接口实现正常工作。由于某种原因,它似乎无法识别类定义中的默认实现。

这是一个示例代码片段:

public interface IFooBar
{
    protected bool BoolProperty { get; set; }
    protected Guid StringProperty { get; set; }
    
    protected void SampleMethod1(string param)
    {
    }
    
    protected void SampleMethod2()
    {
    }
}

public class FooBase
{
}

public class Foo : FooBase, IFooBar
{

    protected bool IFooBar.BoolProperty { get; set; }
    protected Guid IFooBar.StringProperty { get; set; }
    
    protected SomeMethod()
    {
        SampleMethod1("Test String");
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是我的 Visual Studio 2019 项目文件的片段:

<PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework> …
Run Code Online (Sandbox Code Playgroud)

c# .net-core default-interface-member

6
推荐指数
1
解决办法
2077
查看次数