Why implementing multiple interfaces with same property shows 'ambiguity' warning? - c#

Related Post: C# interface method ambiguity
Code from the same source:
private interface IBase1
{
int Percentage { get; set; }
}
private interface IBase2
{
int Percentage { get; set; }
}
private interface IAllYourBase : IBase1, IBase2
{
}
private class AllYourBase : IAllYourBase
{
private int _percentage;
public int Percentage
{
get { return _percentage; }
set { _percentage = value; }
}
}
private void Foo()
{
IAllYourBase iayb = new AllYourBase();
int percentage = iayb.Percentage; // Fails to compile. Ambiguity between 'Percentage' property.
}
(But does not answer my question -- "WHY the contracts become ambiguous? " )
Given:
Interface is a contract that the implementing class MUST abide with.
If two (or more) interfaces ask for the same contract and a interface passes them 'forward' and then class implements both of them and ACCEPTS that the common contracts should serve as just one contract for the implementing classes (by not providing an explicit implementation). Then,
Why does compiler shows 'ambiguity' warning over the common contracts?
Why the compiler fails to compile on trying to access the ambiguous contract through interface( iayb.Percentage) ?
I would like to know what benefit compiler is serving with this restriction?
Edit: Providing a real world use case where I would like to use contracts across interfaces as one contract.
public interface IIndexPriceTable{
int TradeId{get;}
int IndexId{get;}
double Price{get;}
}
public interface ILegPositionTable{
int TradeId {get;}
int LegId {get;}
int Position {get;}
}
public interface ITradeTable {
int TradeId{get;}
int IndexId{get;}
int LegId{get;}
//others
}
public interface IJoinedTableRecord : IIndexPriceTable, ILegPositionTable, ITradeTable {
//Just to put all contracts under one interface and use it as one concrete record, having all information across different tables.
}
Why would I like to have 3-TradeId, 2-LegId, 2-IndexId in my joined table record?

The solution is to define a property Percentage again with new keyword like this:
private interface IBase1
{
int Percentage { get; set; }
}
private interface IBase2
{
int Percentage { get; set; }
}
private interface IAllYourBase : IBase1, IBase2
{
new int Percentage { get; set; }
}
private class AllYourBase : IAllYourBase
{
private int _percentage;
public int Percentage
{
get { return _percentage; }
set { _percentage = value; }
}
}
private void Foo()
{
IAllYourBase iayb = new AllYourBase();
int percentage = iayb.Percentage; //OK
}
Notice:
C# approach to interfaces is very different to approach plan by Bjarne StrouStrup in C++14. In C# you have to claim, that the class implement interface by modifying class itself while in C++14 it only needs to have methods which correspond to interface definition. Thus the code in C# have more dependencies that code in C++14.

Because the interface IAllYourBase does not declare the Percentage property itself.
When you assign an instance of AllYourBase to a variable of IAllYourBase the compiler needs to output a call to either IBase1.Percentage or IBase2.Percentage:
callvirt instance int32 IBase1::get_Percentage()
or
callvirt instance int32 IBase2::get_Percentage()
These are different members on different types and just because they have the same signature doesn't mean they are interchangeable.
In your real world situation you might need finer grained interfaces that define the common properties.

Because the compiler can't figure out which base interface implementation (IBase1.Percentage or IBase2.Percentage) you're trying to access, because your IAllYourBase interface takes after both of them and both of them each have their own Percentage property.
Put it this way: just because two interfaces have a property with the same name and type doesn't mean that the property is intended to work the same way in both interfaces. Even if a common interface inherits from two interfaces with identical members, the compiler can't just combine two seemingly identical properties into one, because they are members of two different contracts.

The line int percentage = iayb.Percentage; has no idea it's dealing with an AllYourBase class, just that whatever it is, it implements the IAllYourBase interface.
So suppose I tried to execute the same statement using my DoubleBase class:
private class DoubleBase : IAllYourBase
{
int IBase1.Percentage { get; set; } = 10;
int IBase2.Percentage { get; set; } = 20;
}
To what value does int percentage get set?

I see your point. I guess the main benefit from this compiler restriction is that it's better to have one, then to not. I.e. there is more harm then your unintentional interface clush will be ignored, then benefit (if there is any) from this strange case there you want such behaviour.
BTW any real-world scenario there desired behaviour will be so much useful?

If an interface inherits two other interfaces that are going to have like-named members, then one of two conditions has to apply:
Both interfaces inherit the same member from some other interface. The other interface will have to be public, but one can document that it exists purely to be inherited, and that consumers are not expected to declare variables or parameters of its type.
The interface which inherits the other interfaces declares as `new` its own member of that same name. This is a good approach when one interface declares a read-only property and another declares a write-only property of the same name; the interface that combines those two interfaces can declare a read-write property whose implementation would be expected to use the read-only property's "getter" and the write-only property's "setter". I'm not sure that it would be good in many other situations, though.
If one does not do one of those things, it's probably best that the compiler not try to guess. Imagine that one has interfaces IListOfDigits, whose Add method appends an integer 0-9 to the list, and IBigNumber, whose Add method adds a number arithmetically. One also has an interface IListOfDigitsRepresentingBigNumber which inherits both. Given an IListOfDigitsRepresentingBigNumber called myThing, holding the digits "5,4,3,2", what should be the effect of myThing.Add(1)? Should it change myThing to hold "5,4,3,2,1" (the effect of IListOfDigits.Add) or "5,4,3,3" (the effect of IBigNumber.Add)? If one does either of the above things, the compiler will have no difficulty figuring out which Add method to use. Otherwise, if both methods can accept an int it won't have a clue.
Incidentally, generics and overloading pose an interesting case. If a IFoo<T,U> has members void Bar(T param) and void Bar(U param), one cannot declare a class as implementing IFoo<int,int>. On the other hand, one can declare a class Foo<T,U> as implementing IFoo<T,U>, and then declare some other class as inheriting from Foo<int,int>, because even if T and U refer to the same type, the compiler would still resolve overloads using T and U.

Related

Why is it illegal to have a private setter on an explicit getter-only interface implementation?

I tend to favor explicit interface implementations over implicit ones, as I think programming against the interface as opposed to against an implementation, is generally preferable, plus when dealing with web-services it is often a necessity.
That said, I was wondering why the following is illegal with an explicit interface declaration and legal with an implicit one:
interface IConnection
{
string ConnectionString { get; }
}
class Connection1 : IConnection
{
// private set is illegal, won't compile
string IConnection.ConnectionString { get; private set; }
}
class Connection2 : IConnection
{
// private set is legal now, it is not part of the interface
string ConnectionString { get; private set; }
}
I know how to fix this, as it is legal to have both an explicit and implicit interface, plus I can make the implicit interface implementation completely private.
Yet I am wondering about the reasoning behind this. Because technically, the internally compiled private method set_IConnection_ConnectionString does not need to be part of the interface, right? It could just be seen as an auxiliary setter, not part of the interface, as it is in the implicit implementation situation.
Update: as a bonus, the seemingly confusing, and in my opinion not quite right compile error you receive is the following:
The accessibility modifier of the accessor must be more restrictive than the property Connection1.ConnectionString
Excuse me, more restrictive than private, how... what?
The only way to invoke an explicit interface member is to cast the object to the correct interface and then invoke the member on that interface. But once you've cast to IConnection, the IConnection.ConnectionString has no setter.
So there's no way to invoke this private setter method.
The problem is that when an interface member is declared explicitly, the compiler generates a private implementation with an "unpronounceable" name, and provides no means by which code--even within the implementing class--to refer to that implementation.
Basically, when one says void IFoo.Moo(), one is saying that one does not wish to define a name Moo within the class scope; consequently, the compiler won't. In order for private set to work, the member would have to be a "pronounceable" name, and the fact that the member was explicitly implemented is taken as an indication that one does not want the name to be Moo.
In practice, the remedy here is probably the same as for many other cases where it's necessary to have an interface implementation whose name is pronounceable, but which is not exposed publicly under its name: declare an interface implementation which does nothing but chain to other members which have the proper accessibility, e.g. if derived classes should not be able to affect the value the value:
private readonly int _foo = whatever;
public int IFOO.Foo { get {return _foo;}}
or, if derived classes should be able to affect it, either
protected int _foo = whatever;
public int IFOO.Foo { get {return _foo;}}
or
private int _foo = whatever;
protected virtual int setFoo(int value) { _foo = value; }
protected virtual int getFoo() { return _foo; }
public int IFOO.Foo { get {return getFoo();}}
In vb.net, interfaces may be implemented using protected class members, but C# offers no such facility.
I think the core of the problem is that the interface only has what it needs. If it isn't public, it naturally isn't part of the interface. When you explicitly implement the interface it does not, therefore, exist.
In the implicit case, your code fits the interface, but is not totally constrained by it. You can add on more things if needed.
Getting information on why this is would require a designer of the language to answer you. It seems logical to me, however: if it isn't part of the interface, you cannot implement/access it as part of the interface.
The property declaration is an atomic thing containing a getter and a setter. It should match the interface.
If you would allow this, then apparently the getter and setter are seen as different things. In that case there is no use to limiting it to privates either. In that case the interface just dictates that there has to be a property which can be read, and you are free to make it writable as well.
Anyway, apparently it's a design decision to make it atomic.
Perhaps the explicit interface implementation should not be seen as part of the class itself but rather as a kind of adapter from your interface to the class. Given this view; consider the following implementation:
public interface I {
string S { get; set; }
}
class C : I {
public C() {
this.S = "Hello World";
//compile error: explicit implementation not accessible
}
string I.S { get; set; }
}
In class C, the property S is not even privately accessible because it is an explicit implementation. Would it not be bad design in the first place to have a concrete implementation of a field not be accessible by the implementation itself?
Furthermore, in your example creating a setter for the explicit implenentation would never be accessible; since the property is only accessible when cast to the IConnection interface. There it only has a getter.

c# Why can't open generic types be passed as parameters?

Why can't open generic types be passed as parameters. I frequently have classes like:
public class Example<T> where T: BaseClass
{
public int a {get; set;}
public List<T> mylist {get; set;}
}
Lets say BaseClass is as follows;
public BaseClass
{
public int num;
}
I then want a method of say:
public int MyArbitarySumMethod(Example example)//This won't compile Example not closed
{
int sum = 0;
foreach(BaseClass i in example.myList)//myList being infered as an IEnumerable
sum += i.num;
sum = sum * example.a;
return sum;
}
I then have to write an interface just to pass this one class as a parameter as follows:
public interface IExample
{
public int a {get; set;}
public IEnumerable<BaseClass> myIEnum {get;}
}
The generic class then has to be modified to:
public class Example<T>: IExample where T: BaseClass
{
public int a {get; set;}
public List<T> mylist {get; set;}
public IEnumerable<BaseClass> myIEnum {get {return myList;} }
}
That's a lot of ceremony for what I would have thought the compiler could infer. Even if something can't be changed I find it psychologically very helpful if I know the reasons / justifications for the absence of Syntax short cuts.
I have been in similar situation, but I never had this (very good!) question. Now that I am forced to think about it, here is my answer:
You expect the following to work:
void F(Example<> e) {
Console.WriteLine(e.a); //could work
}
Yeah, this could theoretically work, but this won't:
void F(Example<> e) {
Console.WriteLine(e.mylist); //?? type unknown
}
You expect the compiler and CLR to be able to analyze method bodies and proove that really no unsafe access is possible in the first case. That could be made to work. Why wasn't it? Probably, the design is not really sound and confusing. Also, "all features are unimplemented by default. Somebody must implement, test and document them."
Edit: I want to point out that this feature cannot be implemented without cooperation from the CLR. The C# compiler must emit the exact method to be called which is not possible on an open generic type. The type system does not even allow such a variable right now.
One implementation rationale: supporting this would require that all non-private generic class methods be made virtual, as otherwise there would be no way to know which specific method to call for an 'open' generic type. There are different jittings of the different closed-type methods, with different corresponding method pointers. Defining an interface manually corresponds to instructing the compiler which methods must be treated as virtual and also allows you to specify exactly which subset of the 'open' functionality you want to expose. What you're proposing is basically that all generic classes have an interface class implicitly generated for the 'open' portion of their public interface, which has performance implications for the class even if this feature is never used.
Maybe I'm not understanding your exact question, but you can make your "MyArbitrarySumMethod" take an arbitrary Example by declaring it like this:
public int MyArbitarySumMethod<T>(Example<T> example) where T : BaseClass
You can then call it without specifying "T":
int sum = MyArbitrarySumMethod(myExampleInstance);
Is that what you're looking for?

The return type of the members on an Interface Implementation must match exactly the interface definition?

According to CSharp Language Specification.
An interface defines a contract that can be implemented by classes and
structs. An interface does not provide implementations of the members
it defines—it merely specifies the members that must be supplied by
classes or structs that implement the interface.
So I a have this:
interface ITest
{
IEnumerable<int> Integers { get; set; }
}
And what I mean is. "I have a contract with a property as a collection of integers that you can enumerate".
Then I want the following interface Implementation:
class Test : ITest
{
public List<int> Integers { get; set; }
}
And I get the following compiler error:
'Test' does not implement interface member 'ITest.Integers'.
'Test.Integers' cannot implement 'ITest.Integers' because it does not
have the matching return type of
'System.Collections.Generic.IEnumerable'.
As long as I can say my Test class implement the ITest contract because the List of int property is in fact an IEnumerable of int.
So way the c# compiler is telling me about the error?
FYI, the feature you want is called "virtual method return type covariance", and as you have discovered, it is not supported by C#. It is a feature of other object-oriented languages, like C++.
Though we get requests for this feature fairly frequently, we have no plans to add it to the language. It is not a terrible feature; if we had it, I'd use it. But we have many reasons not to do it, including that it is not supported by the CLR, it adds new and interesting failure modes to versionable components, Anders does not think it is a very interesting feature, and we have many, many higher priorities and a limited budget.
Incidentally, though people ask us for virtual method return type covariance all the time, no one ever asks for virtual method formal parameter type contravariance, even though logically they are essentially the same feature. That is, I have a virtual method/interface method M that takes a Giraffe, and I would like to override it/implement it with a method M that takes an Animal.
You can't do this because you'd have a major problem on your hand depending on the implementation if this were allowed. Consider:
interface ITest
{
IEnumerable<int> Integers { get; set; }
}
class Test : ITest
{
// if this were allowed....
public List<int> Integers { get; set; }
}
This would allow:
ITest test = new Test();
test.Integers = new HashSet<int>();
This would invalidate the contract for Test because Test says it contains List<int>.
Now, you can use explicit interface implementation to allow it to satisfy both signatures depending on whether it's called from an ITest reference or a Test reference:
class Test : ITest
{
// satisfies interface explicitly when called from ITest reference
IEnumerable<int> ITest.Integers
{
get
{
return this.Integers;
}
set
{
this.Integers = new List<int>(value);
}
}
// allows you to go directly to List<int> when used from reference of type Test
public List<int> Integers { get; set; }
}
Simple fact is, if an interface says:
IInterface{
Animal A { get; }
}
Then an implementation of that property must match the type exactly. Trying to implement it as
MyClass : IInterface{
Duck A { get; }
}
Does not work - even though Duck is an Animal
Instead you can do this:
MyClass : IInterface{
Duck A { get; }
Animal IInterface.A { get { return A; } }
}
I.e. provide an explicit implementation of the IInterface.A member, exploiting the type relationship between Duck and Animal.
In your case this means implementing, the getter at least, ITest.Integers as
IEnumerable<int> ITest.Integers { get { return Integers; } }
To implement the setter, you will need to cast optimistically or use .ToList() on the input value.
Note that the use of A and Integers inside these explicit implementations is not recursive because an explicit interface implementation is hidden from the public view of a type - they only kick in when a caller talks to the type through it's IInterface/ITest interface implementation.
You need 13.4.4 from the specification:
For purposes of interface mapping, a class member A matches an interface member B when:
• A and B are properties, the name and type of A and B are identical, and A has the same accessors as B (A is permitted to have additional accessors if it is not an explicit interface member implementation).
Additionally, your belief that List<int> Integers { get; set; } satisfies the contract of IEnumerable<int> Integers { get; set; } is false. Even if the specification were somehow relaxed to not require that the return types be identical, note that a property of type List<int> with a public setter is not anywhere near the same as a property of type IEnumerable<int> with a public setter because to the latter you can assign an instance of int[], but to the former you can not.
You can do something like this:
interface ITest
{
IEnumerable<int> Integers { get; set; }
}
class Test : ITest
{
public IEnumerable<int> Integers { get; set; }
public Test()
{
Integers = new List<int>();
}
}
Because Test is not an ITest. Why ? With an ITest you can set an array to the property Integers. But you can't with a Test.
With .net 4.0 you can do things like that (covariance and contra-variance) but not exactly that, it's incorrect in every language.

How to hide set method of an implemented property from an interface in C#?

Greetings everyone...
If I have the following interface:
interface IMyInterface
{
int property { get; set; }
}
And the following implementation:
class MyClass : IMyInterface
{
// anything
}
How can I hide the set method of property from the instances of MyClass... In other words, I don't want the set method of property to be public, is that possible?
It would be easy to do with abstract class:
abstract class IMyInterface
{
int property { get; protected set; }
}
Then I could only set the property within the class that implements the abstract class above...
Don't have the set in the interface to begin with. You can still implement it as private.
You can't "hide" it, it's part of the contract. If you don't want it to be part of the contract, don't define it.
If you use the following interface the set method will be unavailable when classes are manipulated via the interface:
interface IMyInterface
{
int property { get; }
}
You could then implement the class like this:
class MyClass : IMyInterface
{
int property { get; protected set; }
}
If some implementations will only implement some parts of an interface, it may be a good idea to subdivide the interface into the parts which each implementation will either implement completely or not at all, and then define interfaces which inherit all the common combinations of them. Adapting your example:
interface IMyReadableInterface
{
int property { get; }
}
interface IMyFullInterface : IMyReadableInterface
{
new int property { get; set; }
}
Classes which want to support read-write access should implement IMyFullInterface; those which want to only support read access should only implement IMyReadableInterface. This segregation will not require any extra work for implementations of either interface which are written in C# and implement property implicitly. Code which implements property in VB, or explicitly implements property in C#, will have to define two implementations of property--a read-only one and a read-write one, but such is life. Note that while one could define an IMyWritableInterface which just had a setter, and have IMyFullInterface inherit both IMyReadableInterface and IMyWritableInterface, IMyFullInterface would still have to define a read-write property of its own, and when using explicit implementation one would then have to define three properties (I really don't understand why C# can't use a read-only and write-only property together as thought they were a read-write property, but it can't).
Assuming you need the setter to be part of the interface but for some reason it does not make sense for it to be used on a particular implementer (in this case MyClass) you can always throw an exception in the setter (such as an InvalidOperationException). This will not protect you at compile time, only at run time. It is a bit strange though, as code that operates on the interface has no idea whether calling the setter is allowed.
There are certainly cases where you want the interface to have a set and then hide it in some concrete class.
I believe the code below shows what we want to accomplish. I.e. the implementation hides the setter, but any IMyInterface aware component will have access to it.
public static void Main()
{
var myClass = new MyClass();
myClass.Property = 123; // Error
((IMyInterface)myClass).Property = 123; // OK
}
It's basically the same pattern you often see for IDisposable.Dispose() where you have an Explicit Interface Implementation. Here's an example for completeness.
public interface IMyInterface
{
int Property { get; set; }
}
public class MyClass : IMyInterface, IDisposable
{
public int Property { get; private set; }
int IMyInterface.Property
{
get => Property;
set => Property = value;
}
void IDisposable.Dispose() {}
}
Too much typing :(
C# doesn't help us much here. Ideally, it would be possible to have an explicit interface implementation for the setter:
// In C# 10 maybe we can do this instead:
public class MyFutureClass : IMyInterface
{
public int Property { get; IMyInterface.set; }
}
See C# feature proposal here.
There is no protected or private in interface, everything is public. Either you don't define any set or use it as public.

Why can't C# interfaces contain fields?

For example, suppose I want an ICar interface and that all implementations will contain the field Year. Does this mean that every implementation has to separately declare Year? Wouldn't it be nicer to simply define this in the interface?
Though many of the other answers are correct at the semantic level, I find it interesting to also approach these sorts of questions from the implementation details level.
An interface can be thought of as a collection of slots, which contain methods. When a class implements an interface, the class is required to tell the runtime how to fill in all the required slots. When you say
interface IFoo { void M(); }
class Foo : IFoo { public void M() { ... } }
the class says "when you create an instance of me, stuff a reference to Foo.M in the slot for IFoo.M.
Then when you do a call:
IFoo ifoo = new Foo();
ifoo.M();
the compiler generates code that says "ask the object what method is in the slot for IFoo.M, and call that method.
If an interface is a collection of slots that contain methods, then some of those slots can also contain the get and set methods of a property, the get and set methods of an indexer, and the add and remove methods of an event. But a field is not a method. There's no "slot" associated with a field that you can then "fill in" with a reference to the field location. And therefore, interfaces can define methods, properties, indexers and events, but not fields.
Interfaces in C# are intended to define the contract that a class will adhere to - not a particular implementation.
In that spirit, C# interfaces do allow properties to be defined - which the caller must supply an implementation for:
interface ICar
{
int Year { get; set; }
}
Implementing classes can use auto-properties to simplify implementation, if there's no special logic associated with the property:
class Automobile : ICar
{
public int Year { get; set; } // automatically implemented
}
Declare it as a property:
interface ICar {
int Year { get; set; }
}
Eric Lippert nailed it, I'll use a different way to say what he said. All of the members of an interface are virtual and they all need to be overridden by a class that inherits the interface. You don't explicitly write the virtual keyword in the interface declaration, nor use the override keyword in the class, they are implied.
The virtual keyword is implemented in .NET with methods and a so-called v-table, an array of method pointers. The override keyword fills the v-table slot with a different method pointer, overwriting the one produced by the base class. Properties, events and indexers are implemented as methods under the hood. But fields are not. Interfaces can therefore not contain fields.
Why not just have a Year property, which is perfectly fine?
Interfaces don't contain fields because fields represent a specific implementation of data representation, and exposing them would break encapsulation. Thus having an interface with a field would effectively be coding to an implementation instead of an interface, which is a curious paradox for an interface to have!
For instance, part of your Year specification might require that it be invalid for ICar implementers to allow assignment to a Year which is later than the current year + 1 or before 1900. There's no way to say that if you had exposed Year fields -- far better to use properties instead to do the work here.
The short answer is yes, every implementing type will have to create its own backing variable. This is because an interface is analogous to a contract. All it can do is specify particular publicly accessible pieces of code that an implementing type must make available; it cannot contain any code itself.
Consider this scenario using what you suggest:
public interface InterfaceOne
{
int myBackingVariable;
int MyProperty { get { return myBackingVariable; } }
}
public interface InterfaceTwo
{
int myBackingVariable;
int MyProperty { get { return myBackingVariable; } }
}
public class MyClass : InterfaceOne, InterfaceTwo { }
We have a couple of problems here:
Because all members of an interface are--by definition--public, our backing variable is now exposed to anyone using the interface
Which myBackingVariable will MyClass use?
The most common approach taken is to declare the interface and a barebones abstract class that implements it. This allows you the flexibility of either inheriting from the abstract class and getting the implementation for free, or explicitly implementing the interface and being allowed to inherit from another class. It works something like this:
public interface IMyInterface
{
int MyProperty { get; set; }
}
public abstract class MyInterfaceBase : IMyInterface
{
int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; }
}
}
Others have given the 'Why', so I'll just add that your interface can define a Control; if you wrap it in a property:
public interface IView {
Control Year { get; }
}
public Form : IView {
public Control Year { get { return uxYear; } } //numeric text box or whatever
}
A lot has been said already, but to make it simple, here's my take.
Interfaces are intended to have method contracts to be implemented by the consumers or classes and not to have fields to store values.
You may argue that then why properties are allowed? So the simple answer is - properties are internally defined as methods only.
Interfaces do not contain any implementation.
Define an interface with a property.
Further you can implement that interface in any class and use this class going forward.
If required you can have this property defined as virtual in the class so that you can modify its behaviour.
Beginning with C# 8.0, an interface may define a default implementation for members, including properties. Defining a default implementation for a property in an interface is rare because interfaces may not define instance data fields.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/interface-properties
interface IEmployee
{
string Name
{
get;
set;
}
int Counter
{
get;
}
}
public class Employee : IEmployee
{
public static int numberOfEmployees;
private string _name;
public string Name // read-write instance property
{
get => _name;
set => _name = value;
}
private int _counter;
public int Counter // read-only instance property
{
get => _counter;
}
// constructor
public Employee() => _counter = ++numberOfEmployees;
}
For this you can have a Car base class that implement the year field, and all other implementations can inheritance from it.
An interface defines public instance properties and methods. Fields are typically private, or at the most protected, internal or protected internal (the term "field" is typically not used for anything public).
As stated by other replies you can define a base class and define a protected property which will be accessible by all inheritors.
One oddity is that an interface can in fact be defined as internal but it limits the usefulness of the interface, and it is typically used to define internal functionality that is not used by other external code.

Categories