使用只读自动属性明确实现接口(C#6功能)

22

在C# 5中,无法使用自动属性显式实现接口但是由于C# 6支持getter-only自动属性, 现在应该可以做到了,对吧?

在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 的原始问题。在我的真实场景中,该值来自注入到构造函数中的对象。如果属性返回的值可以在初始化时设置,则Daniel A. White的答案非常好。

它说:

属性或索引器“IFoo.TestFoo”无法分配-只能读取。

有没有办法绕过这个问题,或者我仍然必须为这种情况使用备份字段的属性?

我使用Visual Studio 2015 RC和Visual Studio Code 0.3.0与DNX451 1.0.0-beta4。

我已经在Roslyn GitHub页面上提出了一个问题


可能的重复问题是关于定义具有可读属性的接口的问题。我的问题是关于使用新的C# 6功能显式实现这样的接口,理论上应该使这成为可能。请参见我在第一句中链接的另一个类似问题(但适用于C# 5,在那里getter-only自动属性尚不可用)。


1
我猜这只是一个bug,或者编译器无法确定它是可设置的,因为它在只读接口后面。 - Daniel A. White
1
@DanielA.White,是的。我猜编译器只允许从构造函数直接访问属性,而强制转换不被允许。 - Nikon the Third
@mikez 这里涉及到了类型转换。 - Daniel A. White
2
@Powerlord,链接问题中的人对接口定义感到困惑(他/她认为它是只读属性定义)。我的问题是关于是否可以使用新的C# 6功能来显式实现一个接口。 - Nikon the Third
显示剩余2条评论
2个回答

4

您可以通过使用只读的后备字段来避免这种情况,用于显式实现属性。您可以在构造函数中将注入的值分配给后备字段,显式属性的获取实现会返回它。

public class Impl : IFoo
{
    private readonly string _testFoo;

    string IFoo.TestFoo => _testFoo;

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

3
我认为你需要这个。
string IFoo.TestFoo { get; } = "World";

也许比我的 string IFoo.TestFoo { get; private set; } 更好的猜测 ;p - leppie
@NikontheThird:我的建议管用吗?我不认为会,但它可能是一个很好的“语法解决方案”来表达意图。在Roslyn GitHub上记录问题可能是值得的。 - leppie
@leppie,遗憾的是,不行,因为这种语法在C# 5中已经是可能的了。但编译器不喜欢private set部分。 - Nikon the Third
@leppie 任何成员的显式实现都不允许声明访问修饰符。 - Mike Zboray
@NikontheThird:是的,我也刚刚查看了一下。我的建议也不是很好... - leppie
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接