-3

I have two classes Inherited from ICart interface

When I create an object from this classes I want only Guest class show me IsInfoExist property. How am I gonna do that?

ICart cart = new Guest();
bool c = cart.IsInfoExist //it's ok

ICart cart = new Member();
cart.IsInfoExist not ok. 

Actually I dont want never appear on intellinsense but Interface force me to show Member IsInfoExist property

class Guest:ICart
{
    public bool IsInfoExist
    {
        get { return Session["guest_info"] != null; }
    }

   public void GetCart()
   {

   }
}

class Member:ICart
{
    //Hide this on intellinsense always!
    public bool IsInfoExist
    {
        get { return false; }
    }


   public void GetCart()
   {

   }
}

public interface ICart
{
   void GetCart();
   bool IsInfoExist { get; }
}
PsyGnosis
  • 1,489
  • 6
  • 21
  • 28
  • 9
    Then don't make `IsInfoExists`part of the interface – Pikoh Mar 07 '17 at 14:26
  • 2
    If you implement the `ICart` interface then you have the members on that interface. By design. Always. If you don't want those members, don't implement that interface. It sounds like what you want is a different interface. – David Mar 07 '17 at 14:27
  • Related: http://stackoverflow.com/questions/56860/what-is-the-liskov-substitution-principle – David Mar 07 '17 at 14:27
  • 2
    That's going against the essence of interfaces. – dcg Mar 07 '17 at 14:27
  • So long as you declare your variables as `ICart`, **no amount** of trickery is going to hide the members. You kinda end up painting yourself into a corner because on one hand you want to hide the implementation in the classes and yet when your main code goes to use `cart`, you have them declared as a `ICart` type! So of course the clients of the code are going to know exactly what members are available –  Mar 07 '17 at 14:40
  • @Pikoh All methods and properties are same for both classes. but only IsInfoExist property part of Guest class. Is there a way to hide it from Member class. And I need that property :) – PsyGnosis Mar 07 '17 at 14:48
  • 2
    Once again. If `IsInfoExists` only must be in `Guest` class, remove it from the interface and leave it as is in the `Guest`class. A class implementing a interface must implement all methods in it, but it can have other methods that does not belong to the interface – Pikoh Mar 07 '17 at 14:49
  • @Pikoh I use ICart it must be. if I remove it. I just use Guest class to that. But I want to use ICart. – PsyGnosis Mar 07 '17 at 14:59
  • @PsyGnosis see my updated answer – Pikoh Mar 07 '17 at 15:03

4 Answers4

3

By explicitly implementing the property:

bool ICart.IsInfoExist
{
    get { return Session["guest_info"] != null; }
}

If you have a Member or a Guest instance, it won't have an IsInfoExist unless you explicitly cast it to an ICart.

Member myMember = new Member();
bool test = myMember.IsInfoExist; // won't compile.
bool test1 = ((ICart) myMember).IsInfoExist; // will compile.
rory.ap
  • 34,009
  • 10
  • 83
  • 174
  • 1
    Actually, the only reason `bool test = myMember.IsInfoExist` won't compile is because you declared `myMember` as `var`. If you declare it as `ICart` as per the OP it compiles perfectly. –  Mar 07 '17 at 14:38
  • Regarding your edit, not sure who's going to remember to type `bool test1 = ((ICart) myMember).IsInfoExist` all the time. Not too readable. Now if the simplest form _hid_ the members by default, and the complex form provided access to the _hidden_ member, then I would agree. :) –  Mar 07 '17 at 15:09
2

If IsInfoExists only must be in Guest class, remove it from the interface and leave it as is in the Guest class. A class implementing a interface must implement all methods in it, but it can have other methods that does not belong to the interface and are specific to that class. Is a nonsense having to implement IsInfoExists in the Member class only to hide it afterwards. So, it would be something like:

public interface ICart
{
     void GetCart();
}    

class Guest:ICart
{
    public bool IsInfoExist
    {
        get { return Session["guest_info"] != null; }
    }

    public void GetCart()
   {
   }
}

class Member:ICart
{ 
    public void GetCart()
    {
    }
}

Edit

It seems the problem with this approach for you is that you are always using variables of type ICart and this way you can't access that method. But you can, you just have to cast it to the correct type,something like this:

ICart cart = new Guest();
ICart cart2 = new Member();

if (cart is Guest)
{
   bool info=((Guest)cart).IsInfoExist;
}

if (cart is Member)
{
   bool info=((Member)cart).IsInfoExist; //this won't compile as IsInfoExist is not in the Member class
}
Pikoh
  • 7,582
  • 28
  • 53
0

Use two interfaces to accomplish that. Like ICart and ICartInfo for example. In this case you have a clear seperation and it would make your code cleaner and better to read.

internetzer
  • 1,373
  • 3
  • 9
  • 9
0

I guess there is no way. Closest solution is

 [Obsolete("Only Guest Member", true)]
        public bool IsInfoExist
        {
            get { return false; }
        }

I'm gonna use this. Thanks

PsyGnosis
  • 1,489
  • 6
  • 21
  • 28