Why an explicit interface member implementation, don't have modifier [duplicate] - c#

This question already has answers here:
Why Explicit Implementation of a Interface can not be public?
(2 answers)
Closed 6 years ago.
Why an explicit interface member implementation, don't have modifier
public interface ITest
{
string Id { get; }
}
public class TestSeparately : ITest
{
//Why an explicit interface member implementation, don't have modifier
string ITest.Id
{
get { return "ITest"; }
}
}

From MSDN
It is not possible to access an explicit interface member implementation through its fully qualified name in a method invocation, property access, or indexer access. An explicit interface member implementation can only be accessed through an interface instance, and is in that case referenced simply by its member name.
Because of this, none of the access modifiers like public, protected or private would make any sense.
Note that this won't work:
TestSeparately ts = new TestSeparately();
string id = ts.Id; // compiler error, because Id is not a public property of TestSeparately
You'd need to case it to ITest:
string id = ((ITest)ts).Id;
So access modifiers are of no use for explicit interface implementations.

By default every member in an interface is public and it has to be that way because interface defines a certain prototype. However a class or structure can inherit from multiple interfaces and it may well be the case that those interfaces have same methods or properties. Consider the following:
public interface ITest
{
string Id { get; }
}
public interface ITest1
{
string Id { get; }
}
public class TestSeparately : ITest, ITest1
{
//Why an explicit interface member implementation, don't have modifier
string ITest.Id
{
get { return "ITest"; }
}
string ITest1.Id
{
get { return "ITest1"; }
}
}
Now if there is a way to cast class to interface implicitly and access members that way, asking property value Id from TestSeparately, I.e return value of TestSeparately.Id is what? Which interface compiler should implicitly cast to and return ID? Is it ITest.Id or ITest1.I'd? See the problem so yes there no modifier in explicit implementation and explicit casting is always required to determine which interface should be targeted and as I said, public is the only access modifier by force and not changeable.

Related

Interface inheritance in c#: property does not inherit get accessor [duplicate]

This question already has answers here:
Adding setter to inherited read-only property in C# interface
(3 answers)
Closed 6 years ago.
Consider the following code:
public interface IFoo
{
int Bar { get; }
}
public interface IModifiableFoo : IFoo
{
int Bar { set; }
}
public class FooImpl : IModifiableFoo
{
public int Bar { get; set; }
}
static void Main()
{
IModifiableFoo f = new FooImpl();
int bar = f.Bar; // Compiler error
}
This is the error message:
error CS0154: The property or indexer 'MyNamespace.IModifiableFoo.Bar' cannot be used in this context because it lacks the get accessor
Since IModifiableFoo inherits IFoo, the get accessor (i.e. get_Bar() method) should be accessible. What is going on here?
Note: This is different from question Adding setter to inherited read-only property in C# interface because that question does not address compiler error in calling getter via writable interface.
The reason is that your IModifiableFoo interface's property hides the one it gets inherited from IFoo, instead of overriding it. So if you want your get functionality in your derived interface, you have to explicitly add it.
Actually, you'd better mark your Bar property in IModifiableFoo with new keyword, to explicitly show that it hides something behind, in order to not get confused when looking up the code.
Getters and setters are not individual members. So a setter in one interface does not add to the getter of the base interface. Instead, interfaces only define members, and that member here is either a readable or writable property.
The inheriting interface defines a property (a member) with the same name as the base interface. So it will hide the base interface’s member. So with two interfaces, you now have two members you could explicitly implement:
int IFoo.Bar { get; }
int IModifiableFoo.Bar { set; }
Note that the compiler should give you a warning about this behavior, and advises you to use the new keyboard in the inheriting interface to mark this as intentional:
public interface IModifiableFoo : IFoo
{
new int Bar { get; set; }
}
Don't use properties and interface inheritance here. Use regular methods and two separate interfaces:
public interface IFooReader
{
int GetBar();
}
public interface IFooWriter
{
void SetBar(int value);
}
public class FooImpl : IFooReader, IFooWriter
{
public int GetBar() { /* ... */ }
public void SetBar(int value) { /* ... */ }
}

Why I cannot implement an interface on a class replacing an interface with a concrete type? [duplicate]

This question already has answers here:
The return type of the members on an Interface Implementation must match exactly the interface definition?
(6 answers)
Does C# support return type covariance?
(9 answers)
Closed 8 years ago.
Why can I not do the following?
public class TestClass : TestInterface
{
public ClassX Property { get; private set; }
}
public interface TestInterface
{
InterfaceX Property { get; }
}
public interface InterfaceX
{
}
public class ClassX : InterfaceX
{
}
The TestInterface Property is readonly, thus can only return InterfaceX as per the contract.
However, I get this compiler error:
'TestClass' does not implement interface member
'TestInterface.InterfaceX'. 'TestClass.InterfaceX' cannot implement
'TestInterface.InterfaceX' because it does not have the matching
return type of 'InterfaceX'.
It does not have the matching type but it has a subclass of that type.
I don't know the spec offhand, but I'm sure there's one that explicitly states that return types must match exactly for interface implementations. The closest I can find is 13.4.4:
For purposes of interface mapping, a class member A matches an interface member B when:
A and B are methods, and the name, type, and formal parameter lists of A and B are identical.
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).
If "type" above means "return type" that would indicate that the return type cannot change.
You could, however, change the return type and explicitly implement the interface with the right return type:
public class TestClass : TestInterface
{
public ClassX InterfaceX { get; private set; }
InterfaceX TestInterface.InterfaceX { get { return InterfaceX; } }
}
UPDATE
According to Eric Lippert it seems to be a CLR limitation, not just a C# one.
You mentioned that you want to expose a reduced set but you want all the functionality internal to the class -- that's not what you want to use an interface for. An interface should only be about your reduced set contract, not also magically function as a full set internally, not without another helper property.
But, there is a way around this limitation while still communicating the contract a little.
interface IExpose<IToolType> where IToolType : ITool
{
IToolType Handler { get; set; }
}
class Expose : IExpose<Tool>
{
public Tool Handler { get; set; }
}
interface ITool
{
}
class Tool : ITool
{
}

Compiler says I am not implementing my interface, but I am?

Okay, I have two namespaces. One contains my interface and one contains the implementing class. Like this:
namespace Project.DataAccess.Interfaces
{
public interface IAccount
{
string SomeMethod();
}
}
namespace Project.DataAccess.Concrete
{
class Account : Project.DataAccess.Interfaces.IAccount
{
string SomeMethod()
{
return "Test";
}
}
}
With this code I get an error:
'Project.DataAccess.Concrete.Account' does not implement interface member 'Project.DataAccess.Interfaces.IAccount.SomeMethod'. 'Project.DataAccess.Concrete.Account.SomeMethod' cannot implement an interface member because it is not public
If I make the class and method public it works fine. But if I instead qualify the method name with the interface name, that fixes it too. Why? Ex:
namespace Project.DataAccess.Concrete
{
class Account : Project.DataAccess.Interfaces.IAccount
{
string IAccount.SomeMethod()
{
return "Test";
}
}
}
Why does this fix it? And why does it have to be public if I don't do that?
To be clear
I am well aware that making it public fixes it. Making the method signature look like this WITHOUT making anything public fixes it:
string IAccount.SomeMethod()
Why?
Interface implementations need to be public or explicit:
Public:
class Account : IAccount
{
public string SomeMethod()
{
return "Test";
}
}
Explicit:
class Account : IAccount
{
string IAccount.SomeMethod()
{
return "Test";
}
}
The default access modifier in C# is private if you do not specify the access modifier.
You have 2 basic options when implementing intefaces: implicit or explicit. Implicit implementation takes on the form of a public method or property, while explicit is in the form of a method or property prefaced with the IFoo. modifier that is otherwise not public.
interface IFoo
{
void Bar();
}
class FooA : IFoo
{
public void Bar() { }
}
class FooB : IFoo
{
void IFoo.Bar() { }
}
The difference here is that in the case of FooA, void Bar is part of the publicly visible API of the class. Code can call Bar via the instance of the class.
FooA foo = new FooA();
foo.Bar(); // legal
In the case of FooB, void Bar is not part of the publicly visible API of the class. The method can still be called, but it must explicitly be called via the interface.
FooB foo = new FooB();
foo.Bar(); // not legal
IFoo myFoo = foo;
myFoo.Bar(); // legal
Your code does not compile because it walks in the uncharted waters between an implicit and explicit interface implementation. You saw that with your change, you had legally defined an explicit implementation, which is why that particular version compiles. Otherwise, you've also found that the public modifer is needed to make the non-explicit version compile.
Methods implementing interface needs to be public. In your later case, you are declaring it explicitly. This is what specification says about explicit interface implementation.
Explicit interface member
implementations have different
accessibility characteristics than
other members. Because explicit
interface member implementations are
never accessible through their fully
qualified name in a method invocation
or a property access, they are in a
sense private. However, since they can
be accessed through an interface
instance, they are in a sense also
public.
'Project.DataAccess.Concrete.Account.SomeMethod' cannot implement an interface member because it is not public
namespace Project.DataAccess.Concrete
{
public class Account : IAccount
{
public string IAccount.SomeMethod()
{
return "Test";
}
}
}
You're not mentioning in your class declaration that you'll be implementing IAccount.
Your class declaration should look like this:
class Account : IAccount
{
//Implementation here.
}
Also, what's happening is that you're using the "default" protection level for Account, and that protection level isn't "public", but an Interface (IAccount) defines public methods by default.
So, when you preface both the Class and Method names with public you're actually implementing the interface. Likewise, when you declare SomeMethod as
IAccount.SomeMethod()
{
//Implementation Here
}
what you're doing is Explicitly Implementing the interface.
I think declaring it explicitly with string IAccount.SomeMethod() works because .NET knows that this implementation of the method can only be accessed through the interface, and so it carries over the public visibility from the interface. In other words, since you are explicitly saying it is an interface member, the compiler can imply that it has to be public, so you don't have to re-state the obvious.
This is also discussed here: http://msdn.microsoft.com/en-us/library/aa664591%28v=vs.71%29.aspx
It is a compile-time error for an
explicit interface member
implementation to include access
modifiers, and it is a compile-time
error to include the modifiers
abstract, virtual, override, or
static.
Explicit interface member
implementations have different
accessibility characteristics than
other members. Because explicit
interface member implementations are
never accessible through their fully
qualified name in a method invocation
or a property access, they are in a
sense private. However, since they can
be accessed through an interface
instance, they are in a sense also
public.
class Account : IAccount
{
public string SomeMethod()
{
return "Test";
}
}
Tell your class to implement the interface. Using the Interface.Method name explicitly implements the method (but i'm not sure why or how) and you need to make them public.
You want to use Interface.Method to explicitly implement an interface requirement when the class already has a member of the same name
class MyClass : IAccount
{
public int SomeMethod() {}
public string IAccount.SomeMethod() {}
}

Contravariance and Entity Framework 4.0: how to specify EntityCollection as IEnumerable?

I have specified a couple of interfaces, which I am implementing as entities using Entity Framework 4. The simplest demonstration code I can come up with is:
public class ConcreteContainer : IContainer
{
public EntityCollection<ConcreteChild> Children { get; set; }
}
public class ConcreteChild : IChild
{
}
public interface IContainer
{
IEnumerable<IChild> Children { get; set; }
}
public interface IChild
{
}
I receive the following compiler error from the above:
'Demo.ConcreteContainer' does
not implement interface member
'Demo.IContainer.Children'.
'Demo.ConcreteContainer.Children'
cannot implement
'Demo.IContainer.Children'
because it does not have the matching
return type of
'System.Collections.Generic.IEnumerable'
My current understanding is that this is because IEnumerable (which is implemented by EntityCollection) is covariant but presumably not contravariant:
This type parameter is covariant. That is, you can use
either the type you specified or any type that is more
derived. For more information about covariance and contravariance,
see Covariance and Contravariance in Generics.
Am I correct, & if so, is there any way I can achieve my goal of specifying the IContainer interface purely in terms of other interfaces rather than using concrete classes?
Or, am I misunderstanding something more fundamental?
The generic variance in .NET 4 is irrelevant here. The implementation of an interface has to match the interface signature exactly in terms of types.
For example, take ICloneable, which looks like this:
public interface ICloneable
{
object Clone();
}
It would be nice to be able to implement it like this:
public class Banana : ICloneable
{
public Banana Clone() // Fails: this doesn't implement the interface
{
...
}
}
... but .NET doesn't allow this. You can sometimes use explicit interface implementation work around this, like so:
public class Banana : ICloneable
{
public Banana Clone()
{
...
}
object ICloneable.Clone()
{
return Clone(); // Delegate to the more strongly-typed method
}
}
However, in your case you can't ever do that. Consider the following code, which would be valid if ConcreteContainer was considered to implement IContainer:
IContainer foo = new ConcreteContainer();
foo.Children = new List<IChild>();
Now your property setter is actually only declared to work with EntityCollection<ConcreteChild>, so it clearly can't work with any IEnumerable<IChild> - in violation of the interface.
As far as I understand, you must implement an interface - you can't assume that a covariant/contra-variant member would be picked up as a substitute.
Even if it was permissible, note that setter for children is an issue. Because it will allow to set property of type EntityCollection<ConcreteChild> with value of any other type such as List<ConcreteChild> or EntityCollection<ConcreteChild2> because both are implementing IEnumerable<IChild>.
In current design, I will implement IContainer privately in ConcreteContainer and check the input value in IEnumerable.Children setter for a compatible type. Another way to approach this design is to have generic interfaces such as:
public interface IContainer<T> where T:IChild
{
IEnumerable<T> Children { get; set; }
}
So you need to implement this interface, right?
public interface IContainer
{
IEnumerable<IChild> Children { get; set; }
}
But in the real class, you want the property to be of type EntityCollection<ConcreteChild>. Here’s how you can do this:
public class ConcreteContainer : IContainer
{
// This is the property that will be seen by code that accesses
// this instance through a variable of this type (ConcreteContainer)
public EntityCollection<ConcreteChild> Children { get; set; }
// This is the property that will be used by code that accesses
// this instance through a variable of the type IContainer
IEnumerable<ConcreteChild> IContainer.Children {
get { return Children; }
set {
var newCollection = new EntityCollection<ConcreteChild>();
foreach (var item in value)
newCollection.Add(item);
Children = newCollection;
}
}
}

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