must implement EITHER interface A OR interface B (exactly one) - c#

I have an interface that looks like this:
public interface IOpportunity
{
string Name { get; }
string Description { get; }
ILocation Location { get; }
}
public interface ILocation : IHierarchicalEntity
{
int OpptyCount { get; }
}
public interface IHierarchicalEntity
{
string SID { get; }
string Name { get; }
}
However, I want the ILocation object to also implement ONE of these interfaces:
public interface IHierarchicalEntityWithParentNames : IHierarchicalEntity
{
/// <summary>
/// Returns the lowest level that this heirarchy goes (0 for a flat hierarchy, 1 for a two-level etc.)
/// </summary>
int LeafLevel { get; }
/// <summary>
/// Returns the name of the Segment for the given level (0 for a root node, n for leaf node, where n = LeafLevel)
/// </summary>
/// <param name="level"></param>
/// <returns></returns>
string GetNameForLevel(int level);
}
public interface IHierarchicalEntityWithParentIds : IHierarchicalEntity
{
IHierarchicalEntityWithParentIds ParentEntity { get; }
string ParentSID { get; }
}
Due to the nature of the code I am writing, I cannot combine these interfaces into one interface that has some sort of GetParent method
In the code that consumes these interfaces, I have two classes - one that consumes the ILocation object if it is an IHierarchicalEntityWithParentNames and another if it is an IHierarchicalEntityWithParentIds
How would I lay out the interfaces (perhaps I have to have some abstract classes) to support having this "one or the other" design?

You can't. You either explicitly implement an interface, or you don't. What you're describing is effectively "either method A or method B will exist," but that's not a concept that exists in C# (or any other language that I'm aware of!).
The closest you'll be able to get would be to throw an exception in the code that consumes your interface if the class doesn't also implement one of the other two interfaces.
Alternatively, I imagine you could have a base class whose constructor will throw an exception if it doesn't also implement one or other of the interfaces. This would give you an earlier check, but it's still a runtime check and, personally, I think it's a horrible idea.

I believe you are over-constraining the true problem. This is very similar to an issue I encountered in my game engine, where coordinates on a hex grid can be either in the canonical reference frame (axes at 120 degress, convenient for most internal game functions) or in the rectangular (user) reference frame with axes at 90 degrees (convenient for most user-visiable game functions).
I addressed this by buidlng a single class Coords that explicitly implements both interfaces ICoordsCanon and ICoordsUser. The actual coordinates are lazily stored and evaluated with an automated conversion like this:
protected static IntMatrix2D MatrixUserToCanon;
protected IntVector2D VectorCanon {
get { return ! isCanonNull ? _vectorCanon
: VectorUser * MatrixUserToCanon; }
set { _vectorCanon = value; isUserNull = true; }
} IntVector2D _vectorCanon;
bool isCanonNull;
protected static IntMatrix2D MatrixCanonToUser;
protected IntVector2D VectorUser {
get { return ! isUserNull ? _vectorUser
: VectorCanon * MatrixCanonToUser; }
set { _vectorUser = value; isCanonNull = true; }
} IntVector2D _vectorUser;
bool isUserNull;
The constructor for Coords is private, with public static functions NewUserCoords(...) and NewCanonCoords(...) defined.
Alhough the implementation is not truly either ... or ..., it APPEARS to be implemented so to the application. Most application usages either works with ICoordsCanon objects, or with ICoordsUser objects; the two methods ICoordsCanon.User() and ICoordsUser.Canon() exist for converting between the two as necessary.
By popular demand, here are the interface definitions and implementations.
public interface ICoordsUser {
int X { get; }
int Y { get; }
IntVector2D Vector { get; set; }
ICoordsCanon Canon { get; }
//ICoordsUser Clone();
string ToString();
int Range(ICoordsUser coords);
IEnumerable<NeighbourCoords> GetNeighbours(Hexside hexsides);
}
public partial class Coords {
int ICoordsUser.X { get { return VectorUser.X; } }
int ICoordsUser.Y { get { return VectorUser.Y; } }
IntVector2D ICoordsUser.Vector { get { return VectorUser; }
set { VectorUser=value; } }
ICoordsCanon ICoordsUser.Canon { get { return this; } }
//ICoordsUser ICoordsUser.Clone() { return NewUserCoords(VectorUser); }
string ICoordsUser.ToString() { return VectorUser.ToString(); }
IEnumerable<NeighbourCoords> ICoordsUser.GetNeighbours(Hexside hexsides) {
return GetNeighbours(hexsides);
}
int ICoordsUser.Range(ICoordsUser coords) { return Range(coords.Canon); }
}
}
and
public interface ICoordsCanon {
int X { get; }
int Y { get; }
IntVector2D Vector { get; set; }
ICoordsCustom Custom { get; }
ICoordsUser User { get; }
//ICoordsCanon Clone();
string ToString();
int Range(ICoordsCanon coords);
IEnumerable<NeighbourCoords> GetNeighbours(Hexside hexsides);
}
public partial class Coords {
int ICoordsCanon.X { get { return VectorCanon.X; } }
int ICoordsCanon.Y { get { return VectorCanon.Y; } }
IntVector2D ICoordsCanon.Vector { get { return VectorCanon; }
set { VectorCanon=value; } }
ICoordsUser ICoordsCanon.User { get { return this; } }
ICoordsCustom ICoordsCanon.Custom { get { return this; } }
//ICoordsCanon ICoordsCanon.Clone() { return NewCanonCoords(this.VectorCanon); }
string ICoordsCanon.ToString() { return VectorCanon.ToString(); }
IEnumerable<NeighbourCoords> ICoordsCanon.GetNeighbours(Hexside hexsides) {
return GetNeighbours(hexsides);
}
int ICoordsCanon.Range(ICoordsCanon coords) { return Range(coords); }
}
Note that I have not included the entire definition of class Coords, as that would simply be far too large a post. The entire implementation is availabel on CodePlex here: HexGrid Utilities

I am not aware of any way to enforce this at compile time. I think you would have to make this a runtime check by using a base class that throws an exception if both interfaces are implemented.
However, that won't stop someone from bypassing your base class and implementing the interfaces themselves, and I know of no way to prevent that.

You can try Code Contracts. Post-condition. Smth like this
[ContractClassFor(typeof(IOpportunity))]
public abstract class OpportunityContract : IOpportunity
{
public ILocation Location
{
get { Contract.Ensures(Contract.Result<ILocation>() is IHierarchicalEntityWithParentNames || Contract.Result<ILocation>() is IHierarchicalEntityWithParentIds); }
}
}

Related

Narrowing a generic interface

I am attempting to write a "Task" system for a game that can take in generic "GameTasks" with Payloads, however I think I am having a problem with covariance.
This is the function that adds the task to the repository
internal void AddTask(IGameTask<IPayload> task)
{
Tasks.Add(task);
Broker.Instance.Publish(new TaskAdded(task));
}
The repository is currently just a list
public List<IGameTask<IPayload>> Tasks { get; } = new();
This is the task and payload I am attempting to add
public interface IBuildTaskPayload : IPayload
{
public float ContributeAmount { get; }
}
/// <summary>
/// Created when a building is placed
/// </summary>
public class BuildTask : IGameTask<IBuildTaskPayload>
{
...
/// <inheritdoc />
public TaskStatus UpdateTask(IBuildTaskPayload updatePayload)
{
Progress += updatePayload.ContributeAmount;
return Progress >= 100 ? TaskStatus.Finished : TaskStatus.Executing;
}
}
And attempting to add it to the repository
TaskRepository.Instance.AddTask(new BuildTask(construction));
This last part fails, as BuildTask cannot be cast to IGameTask. Why is this? And how would I go about achieving this correctly?
You make have to remove the generics from IGameTask<IPayLoad>
You don't show the definition, but to remove the generic parameter you do something like this
public interface IGameTask
{
IPayLoad PayLoad { get; }
}
This solves the problem that you have which stems from the fact that each implementation of IGameTask<> is a different type.
For example
public interface IPayLoad { }
public interface IGameTask
{
IPayLoad PayLoad { get; }
}
public class BuildingAssets : IPayLoad
{
}
public class BuildTask : IGameTask
{
public BuildingAssets PayLoad { get; }
IPayLoad IGameTask.PayLoad { get => PayLoad; }
}
to be used as
List<IGameTask> tasks = new List<IGameTask>();
// fill list
foreach (var task in tasks)
{
if (task is BuildTask build)
{
BuildingAssets assets = build.PayLoad;
}
}

Create a new instance of a generic type at runtime without type checking

The following design is simply a template to show my problem.
public interface IHero
{
string Name { get; }
int Level { get; }
}
public interface IWarlock : IHero
{
string MagicType { get; }
}
public interface IKnight : IHero
{
string CommandHierarchy { get; }
}
public class Warlock : IWarlock, IHero
{
string IWarlock.MagicType { get { throw new NotImplementedException(); } }
string IHero.Name { get { throw new NotImplementedException(); } }
int IHero.Level { get { throw new NotImplementedException(); } }
public Warlock(string name, int level, string magicType)
{
}
}
public class Knight : IKnight, IHero
{
string IKnight.CommandHierarchy { get { throw new NotImplementedException(); } }
string IHero.Name { get { throw new NotImplementedException(); } }
int IHero.Level { get { throw new NotImplementedException(); } }
public Knight(string name, int level, string commandHierarchy)
{
}
}
public class NullHero : IHero
{
public string Name { get { return string.Empty } }
public int Level { get { return -1; } }
}
class Program
{
static void Main(string[] args)
{
}
//Increments the hero's level.
static IHero LevelUp(IHero hero)
{
if (hero is IWarlock)
return new Warlock(hero.Name, hero.Level + 1, (hero as IWarlock).MagicType);
else if (hero is IKnight)
return new Knight(hero.Name, hero.Level + 1, (hero as IKnight).CommandHierarchy);
else
return new NullHero();
}
}
The problem is that next time I add a new hero, I would have to add another if statement in the LevelUp function and this becomes messy.
I know I can use Activator.CreateInstance to create a new instance however there are two problems, 1. all objects are immutable. 2. number and type of parameters in the constructor.
Could anyone please suggest a solution to this problem?
EDIT:
Yes, everyone in the comments section is correct. I can add LevelUp as a definition in the IHero interface.
Maybe I chose the wrong concept to convey my problem but let's assume that I wanted to handle LevelUp outside as shown in the template. Is there a way to tackle my only problem which is to create a new instance of type IHero without having to do type checking?
Since your objects are immutable and you want to keep your level up logic in the specific classes for each hero you would be best to add the LevelUp method to the IHero interface.
public interface IHero
{
string Name { get; }
int Level { get; }
IHero LevelUp();
}
And in your specific hero classes you would implement the LevelUp method like so.
public IHero LevelUp()
{
return new Warlock(this.Name, this.Level + 1, this.MagicType);
}
And you can keep your static leveup function for backwards compatibility, but you should refactor it away.
static IHero LevelUp(IHero hero)
{
return hero.LevelUp();
}

Correct way to encapsulate through generic interfaces

My application consist of server and client, which are independant. They communicate through objects created and modified by server. Client is provided with read-only interfaces of this objects. As far as I know, that's the correct way to keep encapsulation in OOP. See example:
// Client-side
interface IBox<T> where T : ITool
{
IEnumerable<T> Tools { get; }
}
interface ITool
{
void Use();
}
// Server-side
class Box : IBox<Tool>
{
public List<Tool> ToolList = new List<Tool>();
public IEnumerable<ITool> Tools
{
get { return ToolList; }
}
}
class Tool : ITool
{
string _msg = "default msg";
public string Msg
{
get { return _msg; }
set { _msg = value; }
}
public void Use()
{
Console.WriteLine("Tool used! Msg: {0}", _msg);
}
}
As you see, I have to use generics, because my objects form a hierarchy.
That looked nice, until I've decided to add a Room class with interface IRoom, which have to generalize not only IBox, but ITool too:
interface IRoom<B, T>
where B : IBox<T>
where T : ITool
{
IEnumerable<B> Boxes { get; }
}
class Room : IRoom<Box, Tool>
{
public List<Box> BoxList = new List<Box>();
public IEnumerable<Box> Boxes
{
get { return BoxList; }
}
}
Now, imagine that we have a Room consist of not only boxes. I need at least 3 collections of absolutely different things there, which are collections of several types too. So, there must be a huge tree, and my root class become something like: Room : IRoom<Box, Tool1, Tool2, Tool3, Wardrobe, Coat, Jeans, Hat, Table, Computer, Book, Pen>
I'm not sure, that is right. So, I'm asking, what is true OOP-way of implementing my task? (with no reflection, breaking encapsulation, type casting or other bad tricks)
Starting with the .NET Framework 4 and C# 4 you can use IEnumerable's covariance and just avoid using generics.
// Client-side
interface IBox
{
IEnumerable<ITool> Tools { get; }
}
interface ITool
{
void Use();
}
// Server-side
class Box : IBox
{
public List<Tool> ToolList = new List<Tool>();
public IEnumerable<ITool> Tools
{
get { return ToolList; } // With .NET 3.5 and earlier cast here is neccessary to compile
// Cast to interfaces shouldn't be so much of a performance penalty, I believe.
}
}
class Tool : ITool
{
string _msg = "default msg";
public string Msg
{
get { return _msg; }
set { _msg = value; }
}
public void Use()
{
Console.WriteLine("Tool used! Msg: {0}", _msg);
}
}
interface IRoom
{
IEnumerable<IBox> Boxes { get; }
}
class Room : IRoom
{
public List<Box> BoxList = new List<Box>();
public IEnumerable<IBox> Boxes
{
get { return BoxList; } // and here...
}
}
Covariance and contravariance in generics described here: http://msdn.microsoft.com/en-us/library/dd799517.aspx

Is this a good example for representing the abstract factory pattern

Want to check if this a good example for representing the abstract factory pattern.
Here is the theme
Dell (Factory) makes xps (Product)
Dell (Factory) makes inspiron (Product)
hp (Factory) makes envoy (Product)
hp (Factory) makes presario (Product)
BestBuy sells computers.
//Abstract factory
abstract class ComputerFactory
{
public abstract Computer BuildComputer(Computer.ComputerType compType);
}
//Concrete factory
class Dell : ComputerFactory
{
public override Computer BuildComputer(Computer.ComputerType compType)
{
if (compType == Computer.ComputerType.xps)
return (new xps());
else if (compType == Computer.ComputerType.inspiron)
return new inspiron();
else
return null;
}
}
//Concrete factory
class Hp : ComputerFactory
{
public override Computer BuildComputer(Computer.ComputerType compType)
{
if (compType == Computer.ComputerType.envoy)
return (new envoy());
else if (compType == Computer.ComputerType.presario)
return new presario();
else
return null;
}
}
//Abstract product
public abstract class Computer
{
public abstract string Mhz { get; set; }
public enum ComputerType
{
xps,
inspiron,
envoy,
presario
}
}
//Concrete product for DELL
public class xps : Computer
{
string _mhz = string.Empty;
public override string Mhz
{
get
{
return _mhz;
}
set
{
_mhz = value;
}
}
}
//Concrete product for DELL
public class inspiron : Computer
{
string _mhz = string.Empty;
public override string Mhz
{
get
{
return _mhz;
}
set
{
_mhz = value;
}
}
}
//Concrete product for HP
public class envoy : Computer
{
string _mhz = string.Empty;
public override string Mhz
{
get
{
return _mhz;
}
set
{
_mhz = value;
}
}
}
//Concrete product for HP
public class presario : Computer
{
string _mhz = string.Empty;
public override string Mhz
{
get
{
return _mhz;
}
set
{
_mhz = value;
}
}
}
public class BestBuy
{
ComputerFactory compFactory;
Computer comp;
public BestBuy(Computer.ComputerType compType)
{
if (compType == Computer.ComputerType.xps || compType == Computer.ComputerType.inspiron)
compFactory = new Dell();
else
compFactory = new Hp();
comp = compFactory.BuildComputer(compType);
}
public Computer Sell()
{
return comp;
}
}
Thanks in advance.
It is a good example of portions of the pattern. The basic construction of objects is a decent example, however, the logic relies upon a single Computer.ComputerType enum. This enum needs to know, in advance, every type of computer exposed by every factory.
Often, the motivation for using an abstract factory is to abstract that type of hard coded requirement out of the picture. Instead of having a single enum, it might be better to add a ComputerType class, and allow the factory to return a collection of available types. You could then use the ComputerType returned to construct the new systems.
This allows you to add other factories without changing your API, which is one of the major advantages of the abstract factory pattern. Read up on the Abstract Factory Pattern - one of the main points is:
The client does not know (or care) which concrete objects it gets from each of these internal factories since it uses only the generic interfaces of their products.
In this case, you're "hard coding" the known types into the enum, which violates this portion of the pattern.
I'm not Factory pattern expert but here are couple of things I would do differently:
Instead of an abstract class, I would use an Interface. So if "Dell" needed to inherit from another class it could and still be able to be a ComputerFactory by implementing IComputerFactory for example.
The other small thing is use a "switch" instead of an "if/else if" in your BuildComputer function. Who knows how many computers you might end up with in the end.
How would you know which concrete Factory to use between Hp and Dell? You might use something like "Autofac" to "resolve" which factory to use.
I think, in the scenario and code you have provided, there is only one type of product, i.e 'Computer'. There is no family of products involved. So, the abstract factory pattern will not apply here. Instead factory pattern can be used here. I have modified the code below for understanding.
//Abstract factory
abstract class ComputerFactory
{
public abstract Computer BuildComputer(Computer.ComputerType compType);
}
public class ConcreteFactory : ComputerFactory
{
public override Computer BuildComputer(Computer.ComputerType compType)
{
if (compType == Computer.ComputerType.xps)
return (new xps());
else if (compType == Computer.ComputerType.inspiron)
return new inspiron();
else if (compType == Computer.ComputerType.envoy)
return (new envoy());
else if (compType == Computer.ComputerType.presario)
return new presario();
else
return null;
}
}
//Abstract product
public abstract class Computer
{
public abstract string Mhz { get; set; }
public enum ComputerType
{
xps,
inspiron,
envoy,
presario
}
}
//Concrete product for DELL
public class xps : Computer
{
string _mhz = string.Empty;
public override string Mhz
{
get
{
return _mhz;
}
set
{
_mhz = value;
}
}
}
//Concrete product for DELL
public class inspiron : Computer
{
string _mhz = string.Empty;
public override string Mhz
{
get
{
return _mhz;
}
set
{
_mhz = value;
}
}
}
//Concrete product for HP
public class envoy : Computer
{
string _mhz = string.Empty;
public override string Mhz
{
get
{
return _mhz;
}
set
{
_mhz = value;
}
}
}
//Concrete product for HP
public class presario : Computer
{
string _mhz = string.Empty;
public override string Mhz
{
get
{
return _mhz;
}
set
{
_mhz = value;
}
}
}
public class BestBuy
{
ConcreteFactory compFactory;
Computer comp;
public BestBuy(Computer.ComputerType compType)
{
comp = compFactory.BuildComputer(compType);
}
public Computer Sell()
{
return comp;
}
}

Encapsulating Action<T> and Func<T>?

I'm trying to make a design for some sort of IExecutable interface. I will not get into details, but the point is that I have several Actions that need to be executed from a base class. They may take different parameters (no big deal), and they may/may not return a value.
So far, this is my design:
public abstract class ActionBase
{
// ... snip ...
}
public abstract class ActionWithResultBase<T>: ActionBase
{
public abstract T Execute();
}
public abstract class ActionWithoutResultBase: ActionBase
{
public abstract void Execute();
}
So far, each of my concrete actions need to be a child from either ActionWithResultBase or ActionWithoutResult base, but I really don't like that. If I could move the definition of Execute to ActionBase, considering that the concrete class may or may not return a value, I will have achieved my goal.
Someone told me this could be done with using Func and Action, for which I totally agree, but I can't find a way to have that into one single class so that the caller would know if the action is going to return a value or not.
Brief: I want to do something like:
// Action1.Execute() returns something.
var a = new Action1();
var result = a.Execute();
// Action2.Execute() returns nothing.
var b = new Action2();
b.Execute();
If you want a lightweight solution, then the easiest option would be to write two concrete classes. One will contain a property of type Action and the other a property of type Func<T>:
public class ActionWithResult<T> : ActionBase {
public Func<T> Action { get; set; }
}
public class ActionWithoutResult : ActionBase {
public Action Action { get; set; }
}
Then you can construct the two types like this:
var a1 = new ActionWithResult<int> {
CanExecute = true,
Action = () => {
Console.WriteLine("hello!");
return 10;
}
}
If you don't want to make Action property read/write, then you could pass the action delegate as an argument to the constructor and make the property readonly.
The fact that C# needs two different delegates to represent functions and actions is quite annoying. One workaround that people use is to define a type Unit that represents "no return value" and use it instead of void. Then your type would be just Func<T> and you could use Func<Unit> instead of Action. The Unit type could look like this:
public class Unit {
public static Unit Value { get { return null; } }
}
To create a Func<Unit> value, you'll write:
Func<Unit> f = () => { /* ... */ return Unit.Value; }
The following interfaces should do the trick -- it's essentially copying the Nullable pattern
public interface IActionBase
{
bool HasResult { get; }
void Execute() { }
object Result { get; }
}
public interface IActionBase<T> : IActionBase
{
new T Result { get; }
}
public sealed class ActionWithReturnValue<T> : IActionBase<T>
{
public ActionWithReturnValue(Func<T> action) { _action = action; }
private Func<T> _action;
public bool HasResult { get; private set; }
object IActionBase.Result { get { return this.Result; } }
public T Result { get; private set; }
public void Execute()
{
HasResult = false;
Result = default(T);
try
{
Result = _action();
HasResult = true;
}
catch
{
HasResult = false;
Result = default(T);
}
}
}
public sealed class ActionWithoutReturnValue : IActionBase
{
public bool HasResult { get { return false; } }
object IActionBase.Result { get { return null; } }
public void Execute() { //... }
}
You know that you can ignore the return value of a method right? You don't have to use it.
what about something simple:
public class ActionExecuter
{
private MulticastDelegate del;
public ActionExecuter(MulticastDelegate del)
{
this.del = del;
}
public object Execute(params object[] p)
{
return del.DynamicInvoke(p);
}
}

Categories

Resources