问题
Given that an auto property compiles to a get_method, a set_method and a private variable and since C# 8 is introducing default interface methods
Can properties in Interfaces have default implementations?
Especially a get only property?
回答1:
Yes.
Auto properties aren't a special type of property. They are a convenience feature that generates the code needed to store property values in a backing field.
You can specify a default implementation for properties, both for getters and setters. You can try the following code in Sharplab.io
public interface IDimensions
{
int Height {get;set;}
int Width {get;set;}
int Depth {get;set;}
int Weight { get=>0; set{} }
int Density { get=> Weight==0?0:Height*Width*Depth/Weight ; }
}
public class Box:IDimensions
{
public int Height{get;set;}
public int Width{get;set;}
}
Versioning
This demonstrates the versioning scenario. Box
implemented a version of IDimensions
that only included Height
, Width
.
Weight
was added later with a default implementation that returns 0 and ignores writes. Density
was added with a default implementation that returns the volume/density of a box, or 0 if there's no valid weight. Box
didn't have to change even though the interfade did. Even the code generated by the compiler doesn't show any changes to the Box
class.
Classes can replace the default implementations with their own. Nothing prevents Box
from adding int Weight {get;set;}
in the future.
The default implementations are available only through the interface :
IDimensions box=new Box();
Console.WriteLine(box.Density);
Traits
The other scenario handled by default implementations is traits.
Let's assume I want to add the IDensity
trait to any type of item. In most cases, I'd only need the volume and weight of an item to calculate its density :
public interface IDensity
{
int Density
{
get
{
var weight=getWeight();
if (weight==0) return 0;
return getVolume()/weight;
}
}
abstract int getWeight();
abstract int getVolume();
}
This trait will return a simplistic density calculation and force the type it's applied to to implement the int getWeight()
and an int getHeight()
methods:
public class Crate:IDensity
{
//Dummy numbers
public int getWeight()=>55;
public int getVolume()=>100;
}
public class C {
public void M() {
IDensity box=new Cake();
Console.WriteLine(box.Density);
}
}
Another container could override that implementation with its own. Perhaps the container has a complex shape :
public class WeddingCake:IDensity
{
public int getWeight()=>5;
public int getVolume()=>getWeight()/Density;
public int Density=>2;
}
The Sharplab.io link for this example is here
回答2:
No.
The proposal says:
Interfaces may not contain instance state. While static fields are now permitted, instance fields are not permitted in interfaces. Instance auto-properties are not supported in interfaces, as they would implicitly declare a hidden field.
(source)
See also the Channel 9 interview A Preview of C# 8 with Mads Torgersen where they talk about Default Interface Implementations among other things.
Default interface methods is not included in C# 8.0 (beta) which was released with Visual Studio 2019 Preview 1. At the time of writing, the default interface methods prototype is still in development. Refer to Champion "default interface methods".
来源:https://stackoverflow.com/questions/53700939/default-interface-methods-and-default-values-for-auto-properties