0

In my application, some of the entities implement interface A, others implement interface B, and some implement both A and B. How can I force code that looks at these entities that implement both A and B to use the derived interface for A and B?

Here's some examples:

Interface A

public interface IActive
{
   DateTime? StartEffDT { get; set; }
   DateTime? EndEffDT { get; set; }
}

Interface B

public interface ISecured
{
    object SecurityToCheck { get; set; }
}

Interface A and B

public interface IActiveSecured : IActive, ISecured
{
}

Method Example

public void ExampleMethod1(IActive x) { }
public void ExampleMethod2(ISecured y) { }
public void ExampleMethod3(IActiveSecured z) { }

Is there a way to force ExampleMethod1 to only take IActive, but not IActiveSecured?

public void UpdateItem(IActive item) {
    //update the item, if it is currently active
}

If I tried to call UpdateItem with an IActiveSecured item, it would work. No surprise, that's how inheritance works. But what if I want to ensure that you can't call UpdateItem with an IActiveSecured, because the security needs to be checked to make sure that the user is authorized to update the item?

Thanks for the help!

Riddari
  • 1,713
  • 3
  • 26
  • 57
  • 5
    I think you've missed the point of implementing interfaces if you want it to work like that. If it implements an interface, then anything expecting an implementation of that interface should be able to handle it. It shouldn't matter if it's a derived type or not. – mason Dec 05 '17 at 19:26
  • 4
    Definitively your design seems to be a little off... `IActiveSecured` will be accepted as `IActive` since implements the interface...otherwise it should not implement it :) – Claudio Redi Dec 05 '17 at 19:28
  • I agree with the other commenters. If you can provide some explanation of what you're trying to implement with not including the `IActiveSecured` objects, we might be able to help you more. – krillgar Dec 05 '17 at 19:29
  • 1
    related: https://stackoverflow.com/questions/11194903/is-there-a-generic-type-constraint-for-where-not-derived-from – Crowcoder Dec 05 '17 at 19:30
  • @krillgar You're right, I'll add some more clarification to help you guys understand what I'm trying to do here. – Riddari Dec 05 '17 at 19:35
  • Rather than having some items with a security check and some without, it sounds like you should have *all* of your items expose a security check, and those without any actual access should simply provide an object that gives no access. – Servy Dec 05 '17 at 20:26

2 Answers2

1

Create

public interface INonSecured
{}

public interface IActiveNonSecured : IActive, INonSecured
{}

Then change UpdateItem like so:

public void UpdateItem(IActiveNonSecured item)
{} 

The additional surfacing of the "non secured" concept makes your intent far more clearer and prevents the scenario you mentioned.

Kit
  • 20,354
  • 4
  • 60
  • 103
0

You may use this code, but it has bad smell. If there are new interfaces that inherit from IActive - will inevitably complement the code.

public void UpdateItem(IActive item) {
    if(item is IActiveSecured)
        return;
    //do some code
}
Anton Gorbunov
  • 1,414
  • 3
  • 16
  • 24