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.
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());
}
I'm changing a class from public abstract AwesomeClass, to public sealed AwesomeClass. I've also added a new property. All existing members are unchanged. I know that this is a breaking change. Clients that have implemented AwesomeClass or relied on it being abstract via reflection will be broken.
My question is, will clients that have only used members of instances of AwesomeClass that I've provided, be broken (and if yes how)? None of the clients will have a dependency on any of my types that implemented AwesomeClass as they were all internal. I think not, but...
Here is the class before and after:
public abstract class AwesomeClass
{
public abstract Guid SuperGuid { get; set; }
public abstract int SuperInt { get; set; }
}
public sealed class AwesomeClass
{
public Guid SuperGuid { get; set; }
public int SuperInt { get; set; }
public int OtherSuperInt { get; set; }
}
You mean that when you have this:
public abstract class Foo
{
public string Bar;
}
void UpdateFooBar(Foo foo)
{
foo.Bar = "Updated";
}
And you change abstract class Foo to sealed class Foo, will UpdateFooBar(Foo foo) continue to work?
What kept you from trying? But yes, it will.
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.
I have a base DLL which defines some basic structure and operation for a key concept within our business. This dll is then included in specific web services for each vendor that implement the specific business rules for interacting with that vendor. (While the basic concepts are the same the implementations are very different and can change independently.)
In the base dll I have a series of interfaces set up as such
public interface IVendor
{
string Name { get; set; }
}
public interface IVendor<TC> : IVendor where TC : IAccount
{
IEnumerable<TC> Accounts { get; set; }
}
public interface IAccount
{
string Name { get; set; }
}
public interface IAccount<TP, TC> : IAccount where TP : IVendor
where TC : IExecutionPeriod
{
TP Vendor{ get; set; }
IEnumerable<TC> ExecutionPeriods { get; set; }
}
This continues down several more tiers, and everything compiles fine.
The problem comes when I try to implement this down in the service.
public class FirstVendor : IVendor<FirstVendorAccount>
{
public string Name { get; set; }
public IEnumerable<FirstVendorAccount> Accounts { get; set;}
}
public class FirstVendorAccount : IAccount<FirstVendor, FirstVendorExecutionPeriod>
{
public FirstVendor Vendor { get; set; }
public string Name { get; set; }
public IEnumerable<FirstVendorExecutionPeriod> ExecutionPeriods { get; set; }
}
I get a compiler error that IVendor, IAccount, etc. do not have type parameters. Which is particularly odd because when I asked it to implement the interface it included all of the members from both relevant interfaces.
It looks like you have a circular reference - FirstVendorAccount needs to know about FirstVendor before it can compile and vice versa.
Make one of these the 'dominant' class with the generic type, then the other can just return the base interface.
For instance:
public interface IVendor
{
string Name { get; set; }
}
public interface IVendor<TC> : IVendor where TC : IAccount
{
IEnumerable<TC> Accounts { get; set; }
}
public interface IAccount
{
string Name { get; set; }
}
// no longer needs IVendor<TC> before it can be compiled
public interface IAccount<TC> : IAccount where TC : IExecutionPeriod
{
IVendor Vendor{ get; set; }
IEnumerable<TC> ExecutionPeriods { get; set; }
}
It's worth looking at whether you really need all the generic typing - you may be better off with the non-generic underlying interfaces as these will be much easier to code with.