I'm confused about the implementation of interfaces.
According to MSDN ICollection<T> has the property IsReadOnly
-And-
According to MSDN Collection<T> implements ICollection<T>
-So-
I thought that Collection<T> would have the property IsReadOnly.
-However-
Collection<string> testCollection = new Collection<string>();
Console.WriteLine(testCollection.IsReadOnly);
The above code gives the compiler error:
'System.Collections.ObjectModel.Collection<string>' does not contain a definition for 'IsReadOnly' and no extension method 'IsReadOnly' accepting a first argument of type
'System.Collections.ObjectModel.Collection<string>' could be found (are you missing a using directive or an assembly reference?)
-While-
Collection<string> testInterface = new Collection<string>();
Console.WriteLine(((ICollection<string>)testInterface).IsReadOnly);
The above code works.
-Question-
I thought classes implementing interfaces had to implement every property, so why doesn't testCollection have the IsReadOnly property unless you cast it as ICollection<string>?
It is probably implementing the property explicitly.
C# enables you to define methods as "explicitly implemented interface methods/properties" which are only visible if you have a reference of the exact interface. This enables you to provide a "cleaner" API, without so much noise.
Interfaces can be implemented in couple of ways. Explicitly and implicitly.
Explicit Implementation: When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface
Implicit Implementation: These can be accessed the interface methods and properties as if they were part of the class.
IsReadonly property is implemented explicitly therefore it is not accessible via class directly. Take a look here.
Example:
public interface ITest
{
void SomeMethod();
void SomeMethod2();
}
public ITest : ITest
{
void ITest.SomeMethod() {} //explicit implentation
public void SomeMethod2(){} //implicity implementation
}
Related
I came across this problem when i was implementing n interface explicitly using Visual Studio. So the interface contains properties, but when I am implementing the property explicitly in an abstract class, Compiler throws error "The modifier 'public' is not valid for this item".
Refer Below given code.
interface ITest
{
bool MyProperty { get; set; }
}
internal class Test : ITest
{
public bool ITest.MyProperty
{
get
{
return false;
}
set { }
}
}
According to the programming guide, explicit interface implementations always lack an access modifier. You should remove the public keyword.
If you think about it, this makes a lot of sense. There is only one possible access modifier for an explicit interface implementation - the same modifier used for the interface. Thus, you don't need to specify the modifier.
If the interface is marked public, and the explicit implementation is private, that will not make sense. The only reason to write an explicit implementation is to expose that member to only that interface. It would be weird if the member is less accessible than the interface, right?
On the other hand, if the interface is internal and the member is marked public, it will not make sense either. If the member is more accessible than the interface, then it will not be exposed only to the interface.
I have an interface:
public interface Profile
{
string Name { get; }
string Alias { get; set; }
}
All objects that implement Profile have a Name and an Alias, but some restrict Alias such that it's always the same as Name. The ones that apply this restriction can implement Alias like this:
string Profile.Alias
{
get
{
return ((Profile)this).Name;
}
set { }
}
Since this within the context of an explicit interface implementation can only possibly be of type Profile and we know it was accessed through the Profile interface rather than that of the containing class or any other interface it implements, why is the cast required?
Using return this.Name; for the getter implementation results in this error:
Type `ConcreteProfile' does not contain a definition for `Name' and no extension method `Name' of type `ConcreteProfile' could be found (are you missing a using directive or an assembly reference?)
Since this within the context of an explicit interface implementation can only possibly be of type Profile
This is not true. You are implementing Profile.Alias inside the ConcreteProfile class. In this context, this refers to the ConcreteProfile instance and can be used to access any member of the ConcreteProfile instance.
For example, the ConcreteProfile class can contain another Name property that is not Profile.Name. In this case this.Name would refer to that property.
Since you want to access Profile.Name, you have to cast this to Profile.
Since this within the context of an explicit interface implementation can only possibly be of type Profile and we know it was accessed through the Profile interface rather than that of the containing class or any other interface it implements, why is the cast required?
Because it uses explicit interface implementation. That's simply part of what explicit interface implementation does - and part of how it achieves its aim of disambiguating calls that would otherwise be ambiguous. From the C# 5 specification, section 13.4.1:
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.
...
Explicit interface member implementations serve two primary purposes:
Because explicit interface member implementations are not accessible through class or struct instances, they allow interface implementations to be excluded from the public interface of a class or struct. This is particularly useful when a class or struct implements an internal interface that is of no interest to a consumer of that class or struct.
Explicit interface member implementations allow disambiguation of interface members with the same signature. Without explicit interface member implementations it would be impossible for a class or struct to have different implementations of interface members with the same signature and return type, as would it be impossible for a class or struct to have any implementation at all of interface members with the same signature but with different return types.
Why can't I do this?
internal class InsuranceClientFactory : IInsuranceClientFactory
{
internal Iws2SoapClient InsuranceClient()
{
}
}
internal interface IInsuranceClientFactory
{
Iws2SoapClient InsuranceClient();
}
I get the error:
Cannot implement an interface member because it is not public
There are a few questions where the class is public but the interface is not, but both of mine are internal. I don't want to expose this class or interface outside of my assembly. Seems an odd limitation.
This question C# internal interface with internal implementation, does state "If you are implicitly implementing an interface I believe that the member must be declared public." but this doesn't make sense to me, why can't you? seems justified?
"I don't want to expose this class or interface . . ." and that fine.
But the method needs to be public, even if it is public it won't be visible outside the assembly because the class is internal.
If you really REALLY don't want it to be public, you can explicitly implement that method.
internal class InsuranceClientFactory : IInsuranceClientFactory
{
Iws2SoapClient IInsuranceClientFactory.InsuranceClient()
{
}
}
You have to change the method modifier to public
internal class InsuranceClientFactory : IInsuranceClientFactory
{
public Iws2SoapClient InsuranceClient()
{
}
}
Making the method public doesn't mean it can be accessed publicly since the DeclaringType itself internal method will have internal access only.
I can tell you why it doesn't work. C# Language specification 5.0 section 13.4.4, Interface Mapping.
... Neither non-public nor static members participate in interface mapping ...
but because what you are attempting to do should technically work, the explicit implementation is given precedence and your implementation can remain internal
And not to split hairs, but even if you Explicitly Implement the internal interface, the implementation will not be internal it is actually private/public as stated earlier in the specification (Section 13.4.1 Explicit Interface Member 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.
Change it to:
internal class InsuranceClientFactory : IInsuranceClientFactory
{
public Iws2SoapClient InsuranceClient()
{
}
}
The class is still internal and isn't exposing the interface.
I love resharper.
However, I have the following problem:
My naming convention for private methods is camel.
So for so good.
However, when I implement an interface method explicitely as in
void IMyInterface.MyMethod (...)
resharper treats it as a private method and wants to change it to IMyInterface.***m***yMethod.
Is there a way to ignore naming convention for explicit interface implementations?
There was a bug in some versions of ReSharper, and it was fixed long ago. What version do you use? Did you try latest builds, like 4.5.1 or one of the latest nightlies?
Interface methods are not allowed to be private. When explicitly using the interface, you'll use
void IMyInterface.MyMethod(...)
without an accessibility setting. The implementation will be public or internal depending of if the interface is public or internal.
That will not work.
Resharper is using the name provided by the interface itself - and in order to implement it, you cannot change this name (even casing).
"MyMethod" is the name as specified in "IMyInterface". You must preserve the casing in order to implement that method, and since you're explicitly implementing it, there are no options.
Edit after comments:
Here is an example. I just made an interface, like so:
internal interface IMyInterface
{
void testmethod();
}
This violates my current naming conventions (Resharper asks to capitalize testmethod in this case).
If I then make a class that implements this interface:
class MyClass : IMyInterface
{
And I choose to "Implement Interface Explicitly", Resharper creates:
class MyClass : IMyInterface
{
#region IMyInterface Members
void IMyInterface.testmethod()
{
throw new NotImplementedException();
}
#endregion
}
In this case, it does not complain about the casing in the line: void IMyInterface.testmethod()
There would be no way to implement the interface using a different casing than the one in the interface, however - that doesn't matter whether it's explicitly or implicitly defined - the interface determines the name of the method, including the case.
I think the confusion may be due to the fact that you're assuming that, in my case, testmethod is private - it is not a private method, it's a public, explicit implementation of IMyInterface.testmethod, which is why you can do:
IMyInterface myClass = new MyClass();
myClass.testmethod(); // This is public on IMyInterface, not private!
You cannot change the case of the method implementing your interface - this is a .NET restriction, not a Resharper restriction.
using System;
namespace random
{
interface IHelper
{
void HelpMeNow();
}
public class Base : IHelper
{
public void HelpMeNow()
{
Console.WriteLine("Base.HelpMeNow()");
}
}
public class Derived : Base
{
public new void HelpMeNow() ///this line
{
Console.WriteLine("Derived.HelpMeNow()");
}
}
class Test
{
public static void Main()
{
Derived der = new Derived();
der.HelpMeNow();
IHelper helper = (IHelper)der;
helper.HelpMeNow();
Console.ReadLine();
}
}
}
the new keyword in the commented line is a little confusing for me. It jsut mean it overrides the implementation of method in base class.
Why not use override keyword?
It's not really overriding it, it's shadowing it. Given a reference to a Derived object, Base's HelpMeNow function will not be accessible1, and derivedObject.HelpMeNow() will call Derived's implementation.
This is not the same as overriding a virtual function, which HelpMeNow is not. If a Derived object is stored in a reference to a Base, or to an IHelper, then Base's HelpMeNow() will be called, and Derived's implementation will be inaccessible.
Derived derivedReference = new Derived();
Base baseReference = derivedReference;
IHelper helperReference = derivedReference;
derivedReference.HelpMeNow(); // outputs "Derived.HelpMeNow()"
baseReference.HelpMeNow(); // outputs "Base.HelpMeNow()"
helperReference.HelpMeNow(); // outputs "Base.HelpMeNow()"
Of course, if the above is not the desired behavior, and it's usually not, there are two possibilities. If you control Base, simply change HelpMeNow() to virtual, and override it in Derived instead of shadowing it. If you don't control Base, then you can at least fix it halfway, by reimplementing IHelper, like so:
class Derived : Base, IHelper{
public new void HelpMeNow(){Console.WriteLine("Derived.HelpMeNow()");}
void IHelper.HelpMeNow(){HelpMeNow();}
}
This version of Derived uses what's called explicit interface implementation, which allows you to satisfy the contract of implementing an interface without adding the implementation to your class's public interface. In this example, we already have an implementation in Derived's public interface that's inherited from Base, so we have to explicitly implement IHelper to change it2. In this example, we just forward the implementation of IHelper.HelpMeNow to our public interface, which is the shadow of Base's.
So with this change, a call to baseReference.HelpMeNow() still outputs "Base.HelpMeNow()", but a call to helperReference.HelpMeNow() will now output "Derived.HelpMeNow()". Not as good as changing Base's implementation to virtual, but as good as we're gonna get if we don't control Base.
1Exception: it is accessible from within methods of Derived, but only when qualified with base., as in base.HelpMeNow().
2Notice that we also have to declare IHelper as an interface the class implements, even though we inherit this declaration from Base.
In general, if interface IBase implements a member DoSomething, and IDerived inherits/implements Ibase, it expected that IDerived.DoSomething will be synonymous with IBase.DoSomething. In general, this is useful since it saves implementers of the class from having to provide redundant implementations. There are, however, some cases where a derived interface must implement a member which has the same name as a member in the base interface, but which will have to be implemented separately. The most common such situations are (1) the derived method will have a different return type from the base type, or (2) the base interface(s) implements a ReadOnly and/or WriteOnly property(s) with a certain and the derived type should implement a Read-Write property. For whatever reason, if interface IReadableFoo provides a read-only property Foo, IWritableFoo provides a write-only property Foo, and interface IMutableFoo simply inherits both, the compiler won't know whether a reference to Foo refers to IReadableFoo.Foo or IWritableFoo.Foo. Even though only IReadableFoo.Foo can be read, and only IWritableFoo.Foo can be written, neither vb.net nor C# can resolve the overload unless one implements a new read-write property Foo which handles both.