Im kind of new to the whole C#, but basically im writing a plugin based architecture for an app im working on. Every plugin will need to have some basic things as such I have an interface as follows:
interface IPlugin
{
string Username {get;}
string Password {get;}
}
The problem is that the username and password will only be used within the class implementing the interface, as such there is no need to make it public.
So that means I cant use an interface since it is only allowed to be public. I was thinking i could use an abstract class but what is the correct access modifier I would need to put on a class member so that I can implement I can see it when I inherit from the class.
I tried the following but it never worked, and i know why it doesn't, i just don't know what the correct modifier is.
abstract class Plugin
{
private string Username;
}
class Imp : Plugin
{
this.Username = "Taylor";
}
Try to use protected modifier, so that fields can be accessible from subclases
abstract class Plugin
{
protected string Username;
protected string Password;
}
class Imp : Plugin
{
public Imp()
{
base.Username = "Taylor";
base.Password = "Pass";
}
}
You can omit base accesor or use this instead, but I've used to explicitly state what I am changing. It make code a little bit more readable and less ambiguous.
You are looking for the protected modifier.
I think you're looking for the protected keyword, like this:
abstract class Plugin
{
protected string Username;
}
The correct modifier is protected. You are right about using an abstract class and not interface in this case - interface is a contract so that the outside world knows some capabilities of the implementors, while abstract class may (and often does) contain some logic and protected members used by that logic.
You are correct in that Interfaces only expose Public methods and properties. You cannot set access modifiers in interfaces.
Given your case, creating an abstract is probably a correct approach. To make a field or property visible only to classes which inherit from your abstract class, you should use the protected access modifier.
For more information: protected access modifier
In your example:
abstract class Plugin
{
protected string Username;
}
class Imp : Plugin
{
public Imp()
{
this.Username = "Taylor"; // No error here...
}
}
As others said the right approach is to have an abstract class as a base class. This means only your Imp class will be able to access Username. But you can achieve close to that with interfaces, though not exactly.
interface IPlugin
{
string Username { get; }
}
class Imp : IPlugin
{
string IPlugin.Username
{
get { return "Taylor"; }
}
}
The key is explicit implementation of interfaces. Now you wont be able to do:
new Imp().Username; //error
But you will able to do:
((IPlugin)new Imp()).Username; //works
In explicit implementation, Username is public only to the interface instance, not the derived type instance.
As to why private is not allowed, see Non Public Members for C# Interfaces
Related
I'm having a hard time to grasp a solution for the following problem.
I am decoupling the classes with their correspondent interface but I need to extend the class for a new change instead of changing the original implementation in order to be compliant with open close principle.
This the base class HttpRequest implementing IHttpRequest
public class HttpRequest : IHttpRequest
{
public string RawUrl { get; protected set; }
public HttpRequest(string rawUrl)
{
RawUrl = rawUrl;
}
public string GetJsonFromUrl(string url)
{
//
}
}
public interface IHttpRequest
{
string GetJsonFromUrl(string url);
}
and the extended class is UrlMetadataResolver:
public class UrlMetadataResolver : HttpRequest
{
public UrlMetadataResolver(string rawUrl) : base(rawUrl)
{
//
}
}
What should I do? should I created an interface for UrlMetadataResolver (IUrlMetadataResolver)?
If that's the case it becomes even more confusing.
Thanks
It is true that since you don't provide any description on what you want to accomplish, there can't be any complete or specific answer.
But here is a hint or two:
If you're already using the HttpRequest class then probably the best thing is not to change it; in order to be compliant with open close principle, as you said. So yes create a new class.
If the new fuctionality of UrlMetadataResolver class is indeed extending the functionality of the HttpRequest class; meaning it uses the methods of HttpRequest and some additional too, then yes, you should inherit from HttpRequest, to be able to use its methods, and add your new methods in the new class.
And in this case yes, you should create a new interface that inherits from IHttpRequest and extends it. The meaning of an interface is to allow a change in the way the things are implemented, without changing the way the things are done. I.e. you can later use another approach and implement the UrlMetadataResolver functionalities in another way, by another class. Using an interface will allow you to change only that, without changing anything in your business layer, in the references of the IUrlMetadataResolver interface.
Composition is a good practise too, as suggested, but makes more sense in cases where we want to inherit from more than one classes. C# and .NET clearly favors composition over inheritance (and they do well) by not allowing inheritance of more than one class.
If, on the other hand, the new functionality, doesn't extend, but rather overrides the functionality of HttpRequest, then the way to go is to mark the HttpRequest methods as virtual, inherit and override in UrlMetadataResolver.
You can assume of course that you can go both ways; override and extend the HttpRequest class.
You can always of course create a new class UrlMetadataResolver with no relation to the HttpRequest.
Hope I could help,
merry coding!
I recommend creating a base class that implements all methods the classes have in common:
public abstract class HttpBaseRequest : IHttpRequest
{
protected HttpBaseRequest(string rawUrl)
{
RawUrl = rawUrl;
}
public string RawUrl{ get; protected set; }
public string GetJsonFromUrl(string url)
{
return "";
}
}
public class HttpDataRequest : HttpBaseRequest
{
public HttpDataRequest(string rawUrl) : base(rawUrl) { }
}
public class UrlMetadataResolver : HttpBaseRequest
{
public UrlMetadataResolver(string rawUrl) : base(rawUrl) { }
}
If required you can still create an interface IUrlMetadataResolver.
I would like to have an interface for a problem called IProblem. With two methods: Solve() and CheckArguments(). The Problem class will implement the CheckArguments() function because it will be the same for all the problems. But then I have different types of problems like EasyProblem and HardProblem that have different implementations of Solve() method but the CheckArguments() method always be the same and I always want to use the base class Problem()'s implementation.
I would like to have correct modifiers and I'm a bit confused on which method being defined in which class/interface. Not to mention I also have a test project for both these functions.
I'm not sure if your question is "what to use", but I'd suggest an interface and an abstract class:
public interface IProblem {
void Solve();
void CheckArguments();
}
public abstract class Problem : IProblem {
public abstract void Solve();
public void CheckArguments() {
...
}
}
public class EasyProblem : Problem
{
public override void Solve()
{
....
}
}
This way, check arguments is implemented in the base class, all derived classes implement IProblem and every derived class must implement Solve.
If you leave out the interface and only support classes which derive from Problem, you'll make sure that a given class can't give it's own implementation of CheckArguments().
public abstract class Problem {
public abstract void Solve();
public void CheckArguments() {
...
}
}
public class EasyProblem : Problem
{
public override void Solve()
{
....
}
}
...
static Main(string[] args)
{
List<Problem> problemsToSolve = ...
foreach(var problem in problemsToSolve)
{
problem.CheckArguments();
problem.Solve();
}
}
You can try something like:
public interface ISupportArguments
{
bool CheckArguments();
}
public abstract class AbstractProblem : ISupportArguments
{
public bool CheckArguments() {
return true;
}
public abstract void SolveProblem();
}
so every your class derives from AbstractProblem and override it's own version of
SolveProblem(..)
The class structure has been shown by Matten very well.
As regards access modifiers: I'd propose a defensive approach, so that you use the most restrictive access modifier that solves the problem. It is easier to be less restrictive afterwards than to be more restrictive as you might have to explain to some users of your code why they cannot use it anymore.
So for the types (interface and classes): if you don't need them in other assemblies, rather define them as internal. If you want to access the types from your test project, you can use the InternalsVisibleTo attribute to be able to access them from specific assemblies. You add the attribute to the assembly containing the types and provide the name (and for strong named assemblies some additional data) of the test assembly as a parameter.
The same applies to the members. You can also think about implementing the interface explicitly, so you can access the methods only if you access the class via the interface.
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() {}
}
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.
I recently ran into a problem where it seems I need a 'static abstract' method. I know why it is impossible, but how can I work around this limitation?
For example I have an abstract class which has a description string. Since this string is common for all instances, it is marked as static, but I want to require that all classes derived from this class provide their own Description property so I marked it as abstract:
abstract class AbstractBase
{
...
public static abstract string Description{get;}
...
}
It won't compile of course. I thought of using interfaces but interfaces may not contain static method signatures.
Should I make it simply non-static, and always get an instance to get that class specific information?
Any ideas?
You can't.
The place to do this is with Attributes.
Eg
[Name("FooClass")]
class Foo
{
}
If you don't mind deferring to implementations to sensibly implement the Description property, you can simply do
public abstract string ClassDescription {get; }
// ClassDescription is more intention-revealing than Description
And implementing classes would do something like this:
static string classDescription="My Description for this class";
override string ClassDescription { get { return classDescription; } }
Then, your classes are required to follow the contract of having a description, but you leave it to them to do it sensibly. There's no way of specifying an implementation in an object-oriented fashion (except through cruel, fragile hacks).
However, in my mind this Description is class metadata, so I would prefer to use the attribute mechanism as others have described. If you are particularly worried about multiple uses of reflection, create an object which reflects over the attribute that you're concerned with, and store a dictionary between the Type and the Description. That will minimize the reflection (other than run time type inspection, which isn't all that bad). The dictionary can be stored as a member of whatever class that typically needs this information, or, if clients across the domain require it, via a singleton or context object.
If it is static, there is only one instance of the variable, I don't see how inheritance would make sense if we could do what you want to accomplish with static vars in derived classes. Personally I think you are going to far to try to avoid a instance var.
Why not just the classic way?
abstract class AbstractBase
{
protected string _Description = "I am boring abstract default value";
}
class Foo : AbstractBase {
public Foo() {
_Description = "I am foo!";
}
}
Combining static and abstract is somewhat meaningless, yes. The idea behind static is one need not present an instance of the class in order to use the member in question; however with abstract, one expects an instance to be of a derived class that provides a concrete implementation.
I can see why you'd want this sort of combination, but the fact is the only effect would be to deny the implementation use of 'this' or any non-static members. That is, the parent class would dictate a restriction in the implementation of the derived class, even though there's no underlying difference between calling an abstract or 'static abstract' member (as both would need a concrete instance to figure out what implementation to use)
A possible workaround is to define a Singleton of your derived class in your base class with the help of Generics.
import System;
public abstract class AbstractBase<T>
where T : AbstractBase<T>, new()
{
private static T _instance = new T();
public abstract string Description { get; }
public static string GetDescription()
{
return _instance.Description;
}
}
public class DerivedClass : AbstractBase<DerivedClass>
{
public override string Description => "This is the derived Class";
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(DerivedClass.GetDescription());
Console.ReadKey();
}
}
The trick is to tell your AbstractBase<T> some details about how DerivedClass is implemented:
It is newable with where T: new() so it can create a Singleton instance
It derives from itself with where T : AbstractBase<T> so it knows that there will be a implementation of Description
This way _instance contains the Description field which can be called in the static Method GetDescription().
This forces you to overwrite Descriptionin your DerivedClass and allows you to call its value with DerivedClass.GetDescription()
It's not static if it has to be called on an instance.
If you're not calling it on an instance, then there's no polymorphism at play (i.e. ChildA.Description is completely unrelated to ChildB.Description as far as the language is concerned).
You can...
In the abstract class...
protected abstract InWindow WindowInstance { get; set; }
In the derived class...
private static InWindow _instance;
protected override InWindow WindowInstance
{
get => _instance;
set => _instance = value;
}
You could make the "abstract" base method throw an Exception, so then a developer is "warned" if he tries to invoke this method on a child class without overriding.
The downside is that one might extend the class and not use this method. Then refer to other answers provided.