在学习C#中一些较新的语言功能时,我注意到您可以在接口的非静态方法定义中添加abstractvirtual,但我很难理解其用途.

下面是一个例子:

public interface IFoo
{
    // Is there any functional difference between these two?
    abstract string AbstractInstanceMethod();
    string InstanceMethod();

    // Or these two?
    virtual string VirtualInstanceMethod() => "bar";
    string InstanceMethodWithDefaultImplementation() => "bar";
}

我可以看到,对于关键字virtual,您必须提供实现,而对于关键字abstract,您不能提供实现.但这些限制似乎只出现在当前接口上的定义中,所以我不妨 Select 提供一个实现或 Select 不提供一个实现.

在派生接口中,您可以使用关键字new覆盖上面的任何实现,然后在abstractvirtual或默认实现中自由 Select ,而不考虑原始定义.

我还试图通过创建具有不同程度的覆盖/实现的派生类,然后调用它们来查看执行了哪些方法体,从而梳理出任何差异,但它总是与变量定义中使用的类型相匹配.

It seems like the keywords just allow you to be more explicit, but I can't find any documentation that confirms this. Can anyone help with this?

If the keywords are redundant, does anyone know of any Roslyn rules to disallow them? I like to avoid having two ways to write the same thing.

PS-抱歉,如果这是一个愚弄或只是一点文件,我错过了.我发现搜索很困难,因为所有关键字的含义都过载了.

推荐答案

看起来关键字只是让你更明确,但我找不到任何文件来证实这一点.有人能帮上忙吗?

这是正确的,您可以很容易地判断代码上生成的IL,以查看它是否具有相同的属性:

    .method public hidebysig newslot abstract virtual 
        instance string AbstractInstanceMethod () cil managed 
    {
    } // end of method IFoo::AbstractInstanceMethod

    .method public hidebysig newslot abstract virtual 
        instance string InstanceMethod () cil managed 
    {
    } // end of method IFoo::InstanceMethod

    .method public hidebysig newslot virtual 
        instance string VirtualInstanceMethod () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 6 (0x6)
        .maxstack 8

        IL_0000: ldstr "bar"
        IL_0005: ret
    } // end of method IFoo::VirtualInstanceMethod

    .method public hidebysig newslot virtual 
        instance string InstanceMethodWithDefaultImplementation () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 6 (0x6)
        .maxstack 8

        IL_0000: ldstr "bar"
        IL_0005: ret
    } // end of method IFoo::InstanceMethodWithDefaultImplementation

如果这些关键字是多余的,有谁知道罗斯林有什么禁止它们的规则吗?我喜欢避免用两种方式写同样的东西.

没有规则,但如果您愿意,可以很容易地编写自己的分析器.我要指出的是,C#中有很多隐式关键字修饰符,比如字段上有private个,类上有internal个--这不是什么 fresh 事.

Csharp相关问答推荐

Rx.Net -当关闭序列被触发时如何聚合消息并发出中间输出?

C#类主构造函数中的调试参数

我无法在Ubuntu下编译使用microsoft.extension.configurationbuilder jsonapi和mono mcs的c#应用程序

Monty Hall游戏节目模拟给我50/50的结果

并行令牌更新

在. net毛伊岛窗口的深度链接已经创建""

Mongo作为.NET中Testcontainers的副本集

ASP.NET核心MVC SqlException:违反主键约束';PK_USER';.无法在对象';数据库中插入重复的密钥.用户';

try 使用C#ASP.NET收集WMI信息时访问被拒绝,但在PowerShell中工作

反序列化私有成员

使用ExtractIconEx(或其他方式)提取最大的可用图标

将内置的OrderedEumable&Quot;类设置为内部类有什么好处?

Regex字母数字校验

如何更改新创建的实例的变量?

{ or ; expected error如何解决此问题

删除MudRadio时,MudRadioGroup未 Select 正确的MudRadio

使用免费的DotNet库从Azure函数向Azure文件共享上的现有Excel文件追加行

如何为控制器PUT操作绑定对象数组

MudRadioGroup不切换

C#、Visual Studio代码、调试器、错误处理变量请求.未知错误:0x80131502,