C#8.0:具有默认实现的接口的受保护属性

时间:2019-09-15 11:26:05

标签: c# c#-8.0 default-interface-member

说我有以下界面:

public interface IReturnableAs {
  protected String ReturnAs { get; set; }
}
public interface IReturnableAsImage<T> {
  protected String ImageResolution { get; set; }
  public T ReturnAsImage(String imageResolution = "large") {
    ReturnAs = "image";
    ImageResolution = imageResolution;
    return (T)this;
  }
}
public interface IReturnableAsJson<T> {
  protected Boolean IsPretty { get; set; }
  public T ReturnAsJson(Boolean isPretty = false) {
    ReturnAs = "json";
    IsPretty = isPretty;
    return (T)this;
  }
}

public class Foo : IReturnableAsImage<Foo>, IReturnableAsJson<Foo> {...}

最初,这些错误迫使我使用ReturnAsImageResolutionIsPretty属性的实现。使这些实现protectedCS0535结尾,表示未实现属性。另一方面,使这些public给我CS8704,告诉我这种实现是不可能的。

除了抽象类之外,是否还有针对这些错误的解决方法?

1 个答案:

答案 0 :(得分:1)

首先,您要实现什么? Foo.ReturnAs应该返回什么?您将如何使用这些界面?

如果没有从ReturnAs继承,则不能在其他接口中使用IReturnableAs。一旦从该接口继承,Foo就必须提供一个实现。发生这种情况时,无论您如何转换Foo,都将始终获得自己的IReturnableAs实现。

接口不是抽象类,因此只能有一个 接口成员实现。您无法通过不同的界面访问不同的“默认”实现。

通过IReturnableAs访问的

综合结果

如果要为特定接口返回jsonimage,为image;json返回Foo,则最好的选择是使接口 not < / em>从IReturnableAs继承,并提供自己的ReturnAs属性:

public interface IReturnableAs {
  public String ReturnAs { get; }
}
public interface IReturnableAsImage<T>
{
  public String ReturnAs =>"image";

  protected String ImageResolution { get; set; }    
  public T ReturnAsImage(String imageResolution = "large") 
  {
    ImageResolution = imageResolution;
    return (T)this;
  }
}
public interface IReturnableAsJson<T> {
  public String ReturnAs =>"json";

  protected Boolean IsPretty { get; set; }
  public T ReturnAsJson(Boolean isPretty = false) {
    IsPretty = isPretty;
    return (T)this;
  }
}

public class Foo : IReturnableAsImage<Foo>, IReturnableAsJson<Foo> ,IReturnableAs
{
    string IReturnableAs.ReturnAs =>"image;json";

    String IReturnableAsImage<Foo>.ImageResolution { get; set; }="3";
    Boolean IReturnableAsJson<Foo>.IsPretty { get; set; }=false;
}

以下代码:

void Main()
{
  var foo=new Foo();
  Console.WriteLine(((IReturnableAs)foo).ReturnAs);
  Console.WriteLine(((IReturnableAsImage<Foo>)foo).ReturnAs);
  Console.WriteLine(((IReturnableAsJson<Foo>)foo).ReturnAs); 
}

打印:

image;json
image
json

我删除了ReturnAs设置器,因为对于同一接口,有效值将始终相同。

如果要创建一个生成JPG的新类,例如FooJpg,则可以覆盖IReturnableAsImage<T>的默认实现,例如:

public class FooJpg : IReturnableAsImage<FooJpg>, IReturnableAsJson<FooJpg> ,IReturnableAs
{
    string IReturnableAs.ReturnAs =>"jpg;json";

    String IReturnableAsImage<FooJpg>.ImageResolution { get; set; }="3";
    Boolean IReturnableAsJson<FooJpg>.IsPretty { get; set; }=false;

    String IReturnableAsImage<FooJpg>.ReturnAs => "jpg";

}

无论界面如何,结果都相同

如果您希望Foo.ReturnAs始终返回相同的值,例如"image;json",则可以为单个用例添加默认的IReturnAs实现,并为多种用途覆盖该方法:< / p>

public interface IReturnableAs {
  public String ReturnAs { get; }
}

public interface IReturnableAsImage<T>:IReturnableAs
{
  String IReturnableAs.ReturnAs =>"image";

  protected String ImageResolution { get; set; }    
  public T ReturnAsImage(String imageResolution = "large") 
  {    
    ImageResolution = imageResolution;
    return (T)this;
  }
}

public interface IReturnableAsJson<T>:IReturnableAs { 
  String IReturnableAs.ReturnAs =>"json";

  protected Boolean IsPretty { get; set; }
  public T ReturnAsJson(Boolean isPretty = false) {
    //ReturnAs="json";
    IsPretty = isPretty;
    return (T)this;
  }
}

在这种情况下,IReturnableAsImageIReturnableAsJson接口提供了一种实现。对于本课程:

public class Foo : IReturnableAsImage<Foo>
{
    String IReturnableAsImage<Foo>.ImageResolution { get; set; }="3";
}

以下代码将显示image

void Main()
{
  var foo=new Foo();
  Console.WriteLine(((IReturnableAs)foo).ReturnAs);
  Console.WriteLine(((IReturnableAsImage<Foo>)foo).ReturnAs);
}

对于同时使用两个接口的类,需要显式的IReturnableAs实现:

public class FooMulti : IReturnableAsImage<FooMulti>, IReturnableAsJson<FooMulti> 
{
    String IReturnableAs.ReturnAs =>"image;json";

    String IReturnableAsImage<FooMulti>.ImageResolution { get; set; }="3";
    Boolean IReturnableAsJson<FooMulti>.IsPretty { get; set; }=false;
}

在这种情况下,所有呼叫都将返回image;json

void Main()
{
  var foo=new FooMulti();
  Console.WriteLine(((IReturnableAs)foo).ReturnAs);
  Console.WriteLine(((IReturnableAsImage<FooMulti>)foo).ReturnAs);
  Console.WriteLine(((IReturnableAsJson<FooMulti>)foo).ReturnAs); 
}

image;json
image;json
image;json