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() {}
}
Related
Imagine these specifications are from an external dll. A class that implements an interface explicitly:
public interface IDebug
{
string GetImportantInfo();
}
public class ExternalClass : IDebug
{
public void DoSomethingImportant()
{
System.Diagnostics.Debug.WriteLine("Something important was done...");
}
string IDebug.GetImportantInfo() //Explicit implementation
{
DoSomethingImportant();
return nameof(ExternalClass);
}
}
Then this one is from internal code, where you know you need to implement the interface:
public class Debug : ExternalClass, IDebug
{
public string GetImportantInfo()
{
return nameof(Debug);
}
}
Now when I'm calling the Debug's GetImportantInfo() method from the subclass, the explicit implementation in the superclass is not called:
static void Main(string[] args)
{
IDebug test = new Debug();
var impInfo = test.GetImportantInfo();
System.Diagnostics.Debug.WriteLine(impInfo); //"Debug"
}
And the only slight hint I seem to get is that I don't get a compile error when adding the IDebug interface to the Debugclass, without implementing the method:
public class Debug : ExternalClass, IDebug
{
}
Why is there no compile warning when you overwrite a superclass's implementation like this? If the base class implements it implicitly, I get a compile warning telling me to use the new keyword. But using the new keyword to overwrite an explicitly implemented method gives a compile warning:
The member 'Program.Debug.GetImportantInfo()' does not hide an inherited member. The new keyword is not required.
Is there an intended purpose for this, or is this a bug? If it's intended, what is the official reasoning?
The problem here is that you are using a little known feature of the language: interface re-implementation:
public class Debug : ExternalClass, IDebug
{
public string GetImportantInfo()
{
return nameof(Debug);
}
}
Why are you redeclaring that Debug implements IDebug if ExternalClass already does? You are re-implementationing the interface, and becuase you are doing such thing, you get no warning; the compiler assumes you know what you are doing.
If you want the behavior you seem to want, simply don't re-implement the interface:
public class Debug : ExternalClass
{
public string GetImportantInfo()
{
return nameof(Debug);
}
}
If the base class implements it implicitly, I get a compile warning telling me to use the new keyword.
This warning has nothing to do with interface implementation. The warning is simply due to method hiding, you have two methods with the same signature; IDebug is a non factor here, you could put it out of the equation and you'd still get the same warning.
In my colleague's case, he said he had to implement both the base class and the interface because it was an event-based interface.
Well, then tell your colleague to figure out what he wants. If you reimplement the interface, then any call to DoSomething, be it through a Debug typed reference or an IDebug typed reference, should call the reimplemented behavior. Any other behavior would be unexpected and deeply bewildering.
On the other hand, if you need to keep the orignal behavior of the base class if calling DoSomething() through a IDebug typed reference then do not re-implement the interface. What other alternative are you proposing?
Does this mean that you should know about what interfaces the base class implements? Well yes, of course. I find your question about why should anyone know what interfaces any given class you are going to inherit from implements deeply worrisome to be honest.
If you use Explicit implementation than method is not visible in your class without casting to interface.
You will not be able to call
new ExternalClass().GetImportantInfo()
but you can call
((IDebug)new ExternalClass()).GetImportantInfo();
Because of Explicit implementation new keyword is not necessary. You could even add both implementations in one class:
public class ExternalClass : IDebug
{
string IDebug.GetImportantInfo() //Explicit implementation
{
return "Explicit";
}
public string GetImportantInfo()
{
return nameof(ExternalClass);
}
}
Additionally your Debug class does not have to inherit IDebug interface as it inherits ExternalClass. Resharper will show you this as redundant.
internal interface I_Foo
{
void Bar();
}
public abstract class A_Foo : I_Foo
{
public A_Foo() { }
abstract void I_Foo.Bar();
}
public class Foo : A_Foo
{
public Foo() : base() { }
internal override void Bar()
{
}
}
Hello! I'm trying to have some methods visible to outside code, and other only visible to my assembly. For this purpose, I made an internal interface I_Foo to serve as a contract to other parts of the assembly, a public abstract A_Foo to serve as abstraction for external code, and centralize some constructor functionality, and several different classes Foo that implement A_Foo and I_Foo explicitly to retain internal modifier.
However, in the A_Foo class, I get
'A_Foo.I_Foo.Bar()' must declare a body because it is not marked abstract, extern, or partial
even though the method is clearly marked as "abstract". If I add a body, I get "abstract is not a valid modifier".
I need this method to be explicitly declared, in order to be internal in a public class, and I need it to be abstract so I can override it in the actual implementation Foo.
Why doesn't the compiler let me?
Is there another way I can achieve the same thing?
Thank you.
Explicit interface implementations always have to have an actual implementation. The trick here is to making that just call a non-explicit (internal) abstract method:
public abstract class A_Foo : I_Foo
{
// Classes outside the assembly can't derive from A_Foo
// anyway, so let's make the constructor internal...
internal A_Foo() { }
void I_Foo.Bar()
{
Bar(); // Just delegate to the abstract method
}
internal abstract void Bar();
}
This still allows I_Foo to use internal types etc, because Bar is never exposed publicly - but it fits within the other rules of the language.
The method can not be abstract. THe problem is that you try to use explicit interface implementation (void I_Foo.Bar). Those methods can not be overwritten later - so they have to be implemented.
If you declare Bar directly (void Bar()) then it can be abstract.
So this has me perplexed.
Suppose two interfaces.
public interface a
{
void foo();
}
public interface b
{
void foo();
}
Both of those interfaces have a function foo, I have a class that provides explicit implementation:
public class alpha : a, b
{
// why can't I put an access modifier here?
// How would you be able to hide this from a derived class
void a.foo()
{
Console.WriteLine("a");
}
void b.foo()
{
Console.WriteLine("b");
}
}
And a Class that is derived from alpha
public class beta : alpha
{
}
How do you make foo private or protected since alpha doesn't allow access modifiers on explicit imlementation, what can stop someone from calling:
var be = new beta();
(be as b).foo();
EDIT
How come when I don't explicitly provide implementation I can provide an access modifier?
public class alpha : a, b
{
//why this compile?
public void foo()
{
Console.WriteLine("both");
}
}
Since interface a is public, any class that implements a must make the methods of a publicly accessible, either implicitly (through public methods) or explicitly. Explicit implementations are "sort-of" private since they can only be accessed through the interface.
In short, there is no way to completely "hide" foo - your class implements both a and b so those methods must me made accessible through some means.
This would be true even if you only had one interface - having multiple interfaces with a method name collision just forces you to make the implementations explicit. If you had one interface, foo would either have to be public or explicit.
what can stop someone from calling
Nothing, that's the whole point!
beta is a b and thus you can treat it as a b. If you choose to cast it to b and call the explicit foo implementation you'll get b implementation.
As shown in other answers theses are rules of the language and had to be followed.
Sample showing why explicitly specifying public on interface implementation is required:
class Base
{
protected void Foo() { }
}
public interface IFoo
{
void Foo();
}
Class Base explicitly made choice to not expose method Foo to users of the class (except derived, could be private too).
Now if another class wants to derive from Base and implement IFoo at the same time. If language would allow to just pick implementations irrespective of access modifiers it would mean that Base.Foo is now exposed by derived to every caller:
class Derived : Base, IFoo
{
// hypothetical compiler allows to pick any matching `void Foo`
// including inherited `protected void Base.Foo()`
}
This would be clearly against intent of Base class to hide Foo method - so language have to require Foo to be public to be considered as part of interface.
As result you end up with "optional" access modifier on interface implementation where you have exactly one option - must specify public.
Note that Derived has couple options to deal with Foo - explicit implementation and shadowing with new:
class Derived : Base, IFoo
{
new public void Foo() {}
}
Why will my interface not import into my class? I just want to test some interfaces and need to have the one method extended into my class that implements my interface. This I thought would be simple but it is throwing me an error which I will list at the bottom. My method is public and it is throwing me and error. In fact I took the public keyword away and it is still throwing me an error.
Is there a short cut key to import all of the methods into a class.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FlowControl
{
public abstract class Grades : iBase, iFoot
{
public abstract void AddGrade(float grade);
public abstract void ComputeStatistics();
public void WriteGrades(string t)
{
}
public int AddTwo(int a, int b)
{
return 0;
}
void findYourScore() { }
}
public interface iBase
{
public void findYourScore();
}
public interface iFoot
{
}
}
But I get this error:
The modifier 'public' is not valid for this item
You can't specify access modifiers on interface methods, properties, events, or indexers. The interface itself is marked public, therefore all of its members are also implicitly public. However, you will have to specify an access modifier where you're implementing the method (unless you're writing an explicit interface member implementation).
For example:
public abstract class Grades : iBase, iFoot
{
...
public void findYourScore() { }
}
public interface iBase
{
void findYourScore();
}
Further Reading
interface (C# Reference)
Interfaces (C# Programming Guide)
You can't specify the access modifiers inside of interface.You just need to specify signature of the method
public interface iBase
{
void findYourScore();
}
From documentation:
Interfaces can contain methods, properties, events, indexers, or any combination of those four member types. An interface can't contain constants, fields, operators, instance constructors, destructors, or types. Interface members are automatically public, and they can't include any access modifiers. Members also can't be static.
It is as simple as
public interface iBase
{
void findYourScore();
}
Interface members don't need access qualifiers. public is then not valid in this context, as the compiler says.
Interfaces do not specify the protection levels or methods and do not implement them either. Removes the public/private piece and your code will work fine. Classes which implement an interface determine what the access level is. If you need to specify access level use an abstract class instead of an interface.
Ok, so this may be a bit of a silly question, and there's certainly the obvious answer, but I was curious if I've missed any subtleties here.
Is there any difference in terms of visibility/usability between a public member declared in an internal class and an internal member declared in an internal class?
i.e. between
internal class Foo
{
public void Bar()
{
}
}
and
internal class Foo
{
internal void Bar()
{
}
}
If you declared the method as public and also virtual, and then overrode it in a derived class that is public, the reason for using this modifier is clear. However, is this the only situation... am I missing something else?
Consider this case:
public interface IBar { void Bar(); }
internal class C : IBar
{
public void Bar() { }
}
Here C.Bar cannot be marked as internal; doing so is an error because C.Bar can be accessed by a caller of D.GetBar():
public class D
{
public static IBar GetBar() { return new C(); }
}
A commenter asked a follow-up question: is an explicit implementation of an interface method considered to be public, or private? (C# does not allow you to put an access modifier on an explicit implementation.)
Take a step back and think about what exactly is "public" or "private" about a member: people think wrong things like "private means that a method cannot be called from outside the class", but that's not true; the class could make a delegate to a private method, pass it to anyone, and they can then call a private method.
Rather, accessibility determines where the name of a thing can be used! Explicit interface implementations do not add a name to the class declaration space in the first place; they can only be referred to by name via the interface, not the class. It really doesn't make sense to think of explicit interface implementations as public or private because they don't have a name you can refer to.
A public member is still just internal when in an internal class.
From MSDN:
The accessibility of a member can never be greater than the accessibility of its containing type. For example, a public method declared in an internal type has only internal accessibility
Think of it this way, I would access a public property on....? A class I can't see? :)
Eric's answer is very important in this case, if it's exposed via an interface and not directly it does make a difference, just depends if you're in that situation with the member you're dealing with.
public members of an internal class can override public members of public base classes and, therefore, be a little more exposed... if indirectly.
Just faced with another example where there is difference between those two, when used from XAML in WPF.
XAML:
<Button Tag="{x:Static vm:Foo+Bar.e1}" />
Code with internal enum compiles successfully:
internal class Foo
{
internal enum Bar
{
e1,
e2,
}
}
But surprisingly changing it to public results in error:
internal class Foo
{
public enum Bar
{
e1,
e2,
}
}
The last example produces compilation error:
error MC3064: Only public or internal classes can be used within markup. 'Bar' type is not public or internal.
Unfortunately, I can't explain what's wrong with public in this case. My guess is "just because WPF works that way". Just change modifier of the nested class to internal to get rid of error.
If it comes to reflection it matters if the member is public or not:
For example you even could pass a nested private class to a WPF binding and the binding would work against the public properties just as usual.