How to declare explicit a member of a interface?.i.e:
public interface IPerfil
{
int IDPerfil
{
get;
set;
}
int IDMarca
{
get;
set;
}
int IDRegional
{
get;
set;
}
int IDFilial
{
get;
set;
}
}
then
public class ComentariosPerfil : BaseComentarios, IPerfil
{
public int IPerfil.IDFilial
{
get;
set;
}
[...]
I get an compilation error,saying that "public" modifier cannot be applied to this item.
The question is:
I want this property to be public. I can't write modifiers in interface like:
public int IDPerfil
{
get;
set;
}
So,how can I explicitly implement an interface member, and make it Public?
For explicitly implemented interfaces you can't specify the visibility. It is taken from the visibility in the interface's definition.
So in your case use the following. The function will be public because that's the way the IPerfil interface is defined:
public class ComentariosPerfil : BaseComentarios, IPerfil
{
int IPerfil.IDFilial
{
get;
set;
}
No, you can't. Explicitly implemeting an interface means you have to cast it to the interface type first to use the defined contract. All members of an interface are public by default, so a public explicit interface doesn't make any sense because you can't access it from the implementing class in the first place.
Related
I would like to persist a class which implements an interface and can have various subclasses. I am just trying to understand how LiteDB handles this setup.
In particular I have a code structure like so:
public interface IItem
{
string UniqueKey { get; set;
string OtherProperties { get; set; }
}
public class Item : IItem
{
public string UniqueKey { get; set; }
public string OtherProperties { get; set; }
}
public class ItemOne : Item
{
public string ItemOneProperty { get; set; }
}
public class ItemTwo : Item
{
public string ItemTwoProperty { get; set; }
}
public class Main
{
public void Init()
{
// Can this apply to all interface implementations?
BsonMapper.Global.Entity<IItem>().Id(oid => oid.UniqueKey);
// This will apply to Item but not ItemOne or ItemTwo
BsonMapper.Global.Entity<Item>().Id(oid => oid.UniqueKey);
}
}
For reasons of wanting to keep the class structure clean, I do not want to use [BsonId] on the key. This means I need to use the BsonMapper to declare the ID. However, it looks like even though the mapper defines the ID on the base interface, it does not apply to any of the concrete classes.
Ideally, I do not want to declare the ID for every subclass in BsonMapper as - aside from there being many subclasses - it would create an unwanted dependency.
Does anyone know the best approach to solve this issue?
This question already has answers here:
C#: Interface to force list of items inheriting the interface
(3 answers)
Closed 10 months ago.
I am trying to deal with a problem of with interfaces and implementations. See code below.
public interface IMachine
{
string Name { get; set; }
List<IElement> Elements { get; set; }
List<IWire> Wires { get; set; }
}
public class ElementA : IElement { }
public class ElementB : IElement { }
public class WireA : IWire { }
public class WireB : IWire { }
public class MachineA : IMachine
{
public List<ElementA> Elements { get; set; }
public List<WireA> Wires { get; set; }
}
public class MachineB : IMachine
{
public List<ElementB> Elements { get; set; }
public List<WireB> Wires{ get; set; }
}
What I want to do in my program, is to iterate over IMachine elements stored in a list, and then access all Wire and Element members, without taking too much care about the exact type.
Is this even possible? I did some experiments with abstract classes, casting, but I'm stuck.
Well, of course code above will not compile as I get error, that I am missing implementation of interface member.
A/B classes vary in details (basic properties are same, but I use some specific ones for each class), so casting does not work, too.
Your fundamental problem is that a List<WireA> is not a List<IWire>, so you are not fulfilling the interface contract. If you want to access the lists as list of a specific type (rather than List<IElement>, for example) and avoid casting the elements, you could use generics:
public interface IMachine<TElement, TWire> where TElement : IElement, TWire : IWire
{
string Name { get; set; }
List<TElement> Elements { get; set; }
List<TWire> Wires { get; set; }
}
public class MachineA : IMachine<ElementA, WireA>
{
public List<ElementA> Elements { get; set; }
public List<WireA> Wires { get; set; }
}
public class MachineB : IMachine<ElementB, WireB>
{
public List<ElementB> Elements { get; set; }
public List<WireB> Wires{ get; set; }
}
Suppose your IWire required the implementation of GetName() and there existed at least one IWire object in your Wires collection then the code would return whatever was implemented by the instance of IWire's GetName() method.
var machines = new List<IMachine>();
machines.Add(new MachineA());
machines.Add(new MachineB());
machines.Add(new MachineA());
foreach(var machine in machines)
{
Console.WriteLine(machine.Wires[0].GetName());
}
Can I make some properties public only to same interface classes and readonly to all other classes?
You can use explicit implementation, for example:
interface IFoo {
int Value { get; set; }
}
public class Foo : IFoo {
public int Value { get; private set; }
int IFoo.Value {
get { return Value; }
set { Value = value; }
}
}
When accessed via Foo only the get will be accessible; when accessed via IFoo both getter and setter will be accessible.
Any use?
An interface is just something like a contract for classes. It doesn't change the accessibility level.
If a member of a class is public it is public to all classes that can access the class. The only restrictions you can have is the use of internal or protected. internal makes the member public to classes which are defined within the same assembly and protected makes it public to classes derived from the class.
Instead of the interface you can create an abstract base class and make the members protected:
public interface IFoo
{
int Value { get; set; }
}
public abstract class FooBase : IFoo
{
public abstract int Value { get; set; }
protected void ProtectedMethod()
{
}
}
public class Foo : FooBase
{
public int Value { get; set; }
}
However you can not define a member that is accessible by classes that implement a specific interface. There is no access modifier like public-to-IFoo-otherwise-private.
I have a bunch of properties which are common to two classes. I wanted to move those into an interface. Since these properties are both get and set, I'm not sure if I'd be allowed to set them from another class. I am implementing the interface in the class where I'd need these properties, but still I'm not being able to access these properties. My class is as follows:
public class PatchSurveyStartegy : IStrategy
{
public IEnumerable<IEnumerable<PointBase>> ReceiverGrid { get; set; }
public IEnumerable<IEnumerable<PointBase>> SourceGrid { get; set; }
public SourceParameters SourceParameters { get; set;}
public DeploymentParameters DeploymentParameters { get; set; }
public RovParameters RovParameters { get; set; }
}
So, IStrategy is the interface where I want to move all of these properties but I'm not getting access to them in this class:
internal double DeployRemainingLines()
{
return StepsForGivenLines(ReceiverGrid).Sum(step => step.CalculateStepTime());
}
I looked at these links: Interface should not have properties? and c# properties on Interface. Also, I dont want to put them in an abstract class, I want to use an interface.
I'm using interfaces in this case mostly as a handle to an immutable instance of an object. The problem is that nested interfaces in C# are not allowed. Here is the code:
public interface ICountry
{
ICountryInfo Info { get; }
// Nested interface results in error message:
// Error 13 'ICountryInfo': interfaces cannot declare types
public interface ICountryInfo
{
int Population { get; }
string Note { get; }
}
}
public class Country : ICountry
{
CountryInfo Info { get; set; }
public class CountryInfo : ICountry.ICountryInfo
{
int Population { get; set; }
string Note { get; set; }
.....
}
.....
}
I'm looking for an alternative, anybody would have a solution?
VB.NET allows this. So, you can create a VB.NET assembly only with the interface definitions that you need:
Public Interface ICountry
ReadOnly Property Info() As ICountryInfo
Public Interface ICountryInfo
ReadOnly Property Population() As Integer
ReadOnly Property Note() As String
End Interface
End Interface
As for the implementation, C# does not support covariant return types, so you must declare your class like this:
public class Country : ICountry {
// this property cannot be declared as CountryInfo
public ICountry.ICountryInfo Info { get; set; }
public class CountryInfo : ICountry.ICountryInfo {
public string Note { get; set; }
public int Population { get; set; }
}
}
If the end goal is to use this with dependency injection, what's wrong with injecting them into each other instead of nesting?
public interface ICountry
{
ICountryInfo Info { get; }
}
public interface ICountryInfo
{
int Population { get; set; }
string Note { get; set; }
}
and implement as:
public class Country : ICountry
{
private readonly ICountryInfo _countryInfo;
public Country(ICountryInfo countryInfo)
{
_countryInfo = countryInfo;
}
public ICountryInfo Info
{
get { return _countryInfo; }
}
}
public class CountryInfo : ICountryInfo
{
public int Population { get; set; }
public string Note { get; set;}
}
Then once you set up your bindings for ICountry & ICountryInfo, CountryInfo will inject into Country whenever Country is injected.
You could then restrict the binding, if you wanted, to only inject CountryInfo into Country and nowhere else. Example in Ninject:
Bind<ICountry>().To<Country>();
Bind<ICountryInfo>().To<CountryInfo>().WhenInjectedInto<Country>();
You can use namespaces like this:
namespace MyApp
{
public interface ICountry { }
namespace Country
{
public interface ICountryInfo { }
}
}
Then in MyApp namespace you can use Country.ICountryInfo which is close to your requirement. Also using alias helps make the code clear.
This will work just fine, no need to nest:
public interface ICountry
{
ICountryInfo Info { get; }
}
public interface ICountryInfo
{
int Population { get; }
string Note { get; }
}
If ICountryInfo has no reason to exist outside ICountry, then why shouldn't you just put the properties of ICountryInfo in ICountry and dismiss the idea of nested interfaces?
An interface that hasn't a meaning of its own without another interface doesn't make sense to me, as an interface on itself is useless if not implemented by a class.