【问题标题】:Explicit implementation of an interface using a getter-only auto-property (C# 6 feature)使用仅 getter 的自动属性显式实现接口(C# 6 功能)
【发布时间】:2015-06-05 17:46:33
【问题描述】:

使用自动属性实现显式接口was not possible in C# 5,但现在C# 6 支持getter-only auto-properties,现在应该可以了,对吧?

在 C# 6 中创建自动属性成功,但是当尝试在构造函数中为其分配值时,您必须首先将 this 强制转换为接口类型,因为实现是显式的。但这就是 VS 2015 RC 和 VS Code 0.3.0 显示评论中可以看到的错误的地方:

using static System.Console;

namespace ConsoleApp
{
    public interface IFoo { string TestFoo { get; } }

    public class Impl : IFoo
    {
        // This was not possible before, but now works.
        string IFoo.TestFoo { get; }

        public Impl(string value)
        {
            // ERROR: Property or indexer 'IFoo.TestFoo' cannot be assigned to -- it is read only.
            ((IFoo)this).TestFoo = value;
        }
    }

    public class Program
    {
        // Yes, not static. DNX supports that (for constructor DI).
        public void Main(string[] args)
        {
            IFoo foo = new Impl("World");

            WriteLine($"Hello {foo.TestFoo}");
            ReadKey(true);
        }
    }
}

注意:我更新了将常量值设置为TestFoo 的原始问题。在我的真实场景中,值来自注入构造函数的对象。如果属性返回的值可以在初始化时设置,answer by Daniel A. White 非常好。

上面写着:

无法将属性或索引器“IFoo.TestFoo”分配给 -- 它是只读的。

有没有办法解决这个问题,还是我仍然需要在这种情况下使用带有支持字段的属性?

我正在使用带有 DNX451 1.0.0-beta4 的 Visual Studio 2015 RC 和 Visual Studio Code 0.3.0。

我有raised an issue over at the Roslyn GitHub page


possible duplicate 是关于定义具有可读取常规属性的接口的问题。我的问题是关于使用新的 C# 6 功能显式实现这样的接口,理论上,这应该可以实现。请参阅我在第一句中链接的另一个问题以获得类似的问题(但对于 C# 5,其中仅 getter 的自动属性尚不可用)。

【问题讨论】:

  • 我猜它只是一个错误,或者编译器无法确定它是可设置的,因为它位于只读接口后面。
  • @DanielA.White 这与普通属性没有太大区别。 string Foo { get; } 现在是合法的,尽管在这种情况下你可以在构造函数中设置它。
  • @DanielA.White,是的。我猜编译器只允许从构造函数直接访问属性,并且不允许强制转换。
  • @mikez 有演员参与。
  • @Powerlord,链接问题中的人对接口定义感到困惑(他/她认为这是一个仅限 getter 的属性定义)。我的问题是关于是否可以使用新的 C# 6 功能来显式实现接口。

标签: c# c#-6.0


【解决方案1】:

您可以通过为显式实现的属性使用只读支持字段来解决此问题。您可以将注入的值分配给构造函数中的支持字段,显式属性的 get 实现将返回它。

public class Impl : IFoo
{
    private readonly string _testFoo;

    string IFoo.TestFoo => _testFoo;

    public Impl(string value)
    {
        _testFoo = value;
    }
}

【讨论】:

    【解决方案2】:

    我想你想要这个

    string IFoo.TestFoo { get; } = "World";
    

    【讨论】:

    • 可能比我的string IFoo.TestFoo { get; private set; } 想得更好;p
    • 对不起,我应该更清楚一点:赋予TestFoo 的值来自注入构造函数的对象,但谢谢。
    • @NikontheThird:我的建议有效吗?我不认为它会,但它可能是一个很好的“句法解决方案”来表达意图。可能值得在 roslyn github 上记录问题。
    • @leppie, sadly, no,因为这种语法在 C# 5 中已经可以使用。但是编译器不喜欢 private set 部分。
    • @leppie 任何成员的显式实现都不允许声明访问修饰符。
    猜你喜欢
    • 1970-01-01
    • 2021-04-14
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    相关资源
    最近更新 更多