How to hide property inherited Interface in a class - c#

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; }
}

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.

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
}

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.

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

Related

Inherit in generic classes C#

My brain is gonna to explode. :) So I would like to get help from you.
Please, think about my question like about just programmer puzzle. (Actually. perhaps it is very easy question for you, but not for me.)
It is needed to create array of objects. For example List where T is class. (I will describe Class T below). Also it is needed create “container” that will contain this array and some methods for work with this array. For example Add(), Remove(int IndexToRemove).
Class T must have field "Container", this way each elements of our array would be able to know where is it contained and has access its container's fields and methods. Notice, that in this case Class T should have type parameter. Indeed, it is not known beforehand which container's type is used.
Let us denote this class container as A and class element (class T) as AUnit.
Code:
class Program
{
static void Main(string[] args)
{
A a = new A();
a.Add();
a.Units[0].SomeField +=100;
Console.ReadKey();
}
}
class A
{
public List<AUnit> Units;
public A()//ctor
{
Units = new List<AUnit>();
}
public void Add()
{
this.Units.Add(new AUnit(this));
}
}
class AUnit
{
public int SomeField;
public A Container;
public string Name { get; private set; }
public AUnit(A container)
{
this.SomeField = 43;
this.Container = container;
this.Name = "Default";
}
}
Public fields should be protected or private of course, but let think about this later.
You can ask “why we create public A Container field in AUnit”? We create field public string Name{get;private set;} (actually property but nevermind). And also we would like to be able to change value of this field for example method [Class AUnit] public bool Rename(string newName)();. The main idea of this method is changing Name field only that case if no one element in array (public List Units; ) has the same name like newName. But to achieve this, Rename method has to have access to all names that is currently used. And that is why we need Container field.
Code of extended version AUnit
class AUnit
{
public int SomeField;
public A Container;
public string Name { get; private set; }
public AUnit(A container)
{
this.SomeField = 43;
this.Container = container;
this.Name = "Default";
}
public bool Rename(String newName)
{
Boolean res = true;
foreach (AUnit unt in this.Container.Units)
{
if (unt.Name == newName)
{
res = false;
break;
}
}
if (res) this.Name = String.Copy(newName);
return res;
}
}
Ok. If you still read it let's continue. Now we need to create Class B and class BUnit which will be very similar like Class A and Class Aunit. And finally the main question of this puzzle is HOW WE CAN DO IT? Of course, I can CopyPaste and bit modify A and AUnit and create this code.
class B
{
public List<BUnit> Units; //Only Type Changing
public B()//ctor Name changing...
{
Units = new List<BUnit>();//Only Type Changing
}
public void Add()
{
this.Units.Add(new BUnit(this));//Only Type Changing
}
}
class BUnit
{
public int SomeField;
public B Container;//Only Type Changing
public string Name { get; private set; }
public A a; //NEW FIELD IS ADDED (just one)
public BUnit(B container) //Ctor Name and arguments type changing
{
this.SomeField = 43;
this.Container = container;
this.Name = "Default";
this.a=new A(); //New ROW (just one)
}
public bool Rename(String newName)
{
Boolean res = true;
foreach (BUnit unt in this.Container.Units) //Only Type Changing
{
if (unt.Name == newName)
{
res = false;
break;
}
}
if (res) this.Name = String.Copy(newName);
return res;
}
}
And I can to use this classes this way.
static void Main(string[] args)
{
B b = new B();
b.Add();
b.Units[0].a.Add();
b.Units[0].a.Units[0].SomeField += 100;
bool res= b.Units[0].a.Units[0].Rename("1");
res = b.Units[0].a.Units[0].Rename("1");
Console.ReadKey();
}
This construction is can be used to create “non-homogeneous trees”.
Help, I need somebody help, just no anybody…. [The Beatles]
I created B and BUnit using CopyPaste.
But how it can be done using “macro-definitions” or “Generic”, inherit or anything else in elegant style? (C# language)
I think that there is no reason to describe all my unsuccessful attempts and subquestions. Already topic is too long. : )
Thanks a lot if you still read it and understand what I would like to ask.
You need to implement a base type, lets call it UnitBase, with all common functionality. I'd structure your code the following way:
Create an interface for your container, this way you can change implementation to more performant solutions without modifying the elements you will be adding to the container.
public interface IContainer
{
Q Add<Q>() where Q : UnitBase, new();
IEnumerable<UnitBase> Units { get; }
}
Following the idea stated in 1, why not make the search logic belong to the container? It makes much more sense, as it will mostly depend on how the container is implemented:
public interface IContainer
{
Q Add<Q>() where Q : UnitBase, new();
IEnumerable<UnitBase> Units { get; }
bool Contains(string name);
}
A specific implementation of IContainer could be the following:
public class Container : IContainer
{
public Container()
{
list = new List<UnitBase>();
}
private List<UnitBase> list;
public Q Add<Q>() where Q: UnitBase, new()
{
var newItem = Activator.CreateInstance<Q>();
newItem.SetContainer(this);
list.Add(newItem);
return newItem;
}
public IEnumerable<UnitBase> Units => list.Select(i => i);
public bool Contains(string name) =>
Units.Any(unit => unit.Name == name);
}
Create a base class for your AUnit and BUnit types condensing all common functionality:
public abstract class UnitBase
{
protected UnitBase()
{
}
public IContainer Container { get; private set; }
public int SomeField;
public string Name { get; private set; }
public void SetContainer(IContainer container)
{
Container = container;
}
public bool Rename(String newName)
{
if (Container.Contains(newName))
return false;
this.Name = newName; //No need to use String.Copy
return true;
}
}
Implement your concrete types:
public class BUnit : UnitBase
{
public int SpecificBProperty { get; private set; }
public BUnit()
{
}
}
Shortcomings of this approach? Well, the container must be of type <UnitBase>, I've removed the generic type because it really wasn't doing much in this particular case as it would be invariant in the generic type.
Also, keep in mind that nothing in the type system avoids the following:
myContainer.Add<BUnit>();
myContainer.Add<AUnit>();
If having two different types in the same container is not an option then this whole set up kind of crumbles down. This issue was present in the previous solution too so its not something new, I simply forgot to point it out.
InBetween , I am very thankful to you for your advices. Actually I can't say that I understood your answer in full, but using your ideas I have done what I want.
Looks like my variant works well. However I would like to hear your (and everyone) opinions about code described below. The main goal of this structure is creating non-homogeneous trees. So could you estimate it from this side.
First of all. We need to create interfaces for both classes. We describe there all "cross-used" functions.
public interface IUnit<T>
{
string Name { get;}
void SetContainer(T t);
bool Rename(String newName);
}
public interface IContainer
{
bool IsNameBusy(String newName);
int Count { get; }
}
Next. Create Base for Unit Classes for future inheritance. We will use in this inheritors methods from Container Base so we need generic properties and IUnit interface.
class UnitBase<T> : IUnit<T> where T : IContainer
Unfortunately I don't know yet how to solve the problem with Constructor parameters. That is why I use method
SetContainer(T container).
Code:UnitBase
class UnitBase<T> : IUnit<T> where T : IContainer
{
protected T Container;
public string Name { get; private set; }
public UnitBase()
{
this.Name = "Default";
}
public void SetContainer(T container)
{
this.Container = container;
}
public bool Rename(String newName)
{
bool res = Container.IsNameBusy(newName);
if (!res) this.Name = String.Copy(newName);
return !res;
}
}
Next. Create ContainerBase
ContainerBase should:
1) has IContainer interface.
2)has information about what it will contain:
... where U : IUnit<C>, new()
3)and .... has information about what itself is. This information we need to pass as parameter to SetContainer() method.
Code ContainerBase:
class ContainerBase<U, C> : IContainer //U - Unit Class. C-Container Class
where U : IUnit<C>, new()
where C : ContainerBase<U, C>
{
protected List<U> Units;
public U this[int index] { get { return Units[index]; } }
public ContainerBase()//ctor
{
this.Units = new List<U>();
}
public void Add()
{
this.Units.Add(new U());
this.Units.Last().SetContainer(((C)this));//may be a bit strange but actualy this will have the same type as <C>
}
public bool IsNameBusy(String newName)
{
bool res = false;
foreach (var unt in this.Units)
{
if (unt.Name == newName)
{
res = true;
break;
}
}
return res;
}
public int Count { get { return this.Units.Count; } }
}
Cast ((TContainer)(this)) may be is a bit strange. But using ContainerBase we always should use NewInheritorContainer. So this cast is just do nothing…looks like...
Finally. This classes can be used like in this example.
class SheetContainer : ContainerBase<SheetUnit,SheetContainer> {public SheetContainer(){}}
class SheetUnit : UnitBase<SheetContainer>
{
public CellContainer Cells;
public PictureContainer Pictures;
public SheetUnit()
{
this.Cells = new CellContainer();
this.Pictures = new PictureContainer();
}
}
class CellContainer : ContainerBase<CellUnit, CellContainer> { public CellContainer() { } }
class CellUnit : UnitBase<CellContainer>
{
public string ValuePr;//Private Field
private const string ValuePrDefault = "Default";
public string Value//Property for Value
{
//All below are Just For Example.
get
{
return this.ValuePr;
}
set
{
if (String.IsNullOrEmpty(value))
{
this.ValuePr = ValuePrDefault;
}
else
{
this.ValuePr = String.Copy(value);
}
}
}
public CellUnit()
{
this.ValuePr = ValuePrDefault;
}
}
class PictureContainer : ContainerBase<PictureUnit, PictureContainer> { public PictureContainer() { } }
class PictureUnit : UnitBase<PictureContainer>
{
public int[,] Pixels{get;private set;}
public PictureUnit()
{
this.Pixels=new int[,]{{10,20,30},{11,12,13}};
}
public int GetSizeX()
{
return this.Pixels.GetLength(1);
}
public int GetSizeY()
{
return this.Pixels.GetLength(0);
}
public bool LoadFromFile(string path)
{
return false;
}
}
static void Main(string[] args)
{
SheetContainer Sheets = new SheetContainer();
Sheets.Add();
Sheets.Add();
Sheets.Add();
Sheets[0].Pictures.Add();
Sheets[1].Cells.Add();
Sheets[2].Pictures.Add();
Sheets[2].Cells.Add();
Sheets[2].Cells[0].Value = "FirstTest";
bool res= Sheets[0].Rename("First");//res=true
res=Sheets[2].Rename("First");//res =false
int res2 = Sheets.Count;
res2 = Sheets[2].Pictures[0].Pixels[1, 2];//13
res2 = Sheets[2].Pictures.Count;//1
res2 = Sheets[1].Pictures.Count;//0
res2 = Sheets[0].Pictures[0].GetSizeX();//3
Console.ReadKey();
}
Looks like it works like I want. But I didn’t test it full.
Let me say Thank you again, InBetween.

C# Why can't interfaces implement methods like this? What is a workaround to solve my issue?

Why can't interfaces implement methods like this?
public interface ITargetableUnit {
//Returns whether the object of a class that implements this interface is targetable
bool unitCanBeTargeted(){
bool targetable = false;
if(this is Insect){
targetable = (this as Insect).isFasterThanLight();
}
else if(this is FighterJet){
targetable = !(this as FighterJet).Flying;
}
else if(this is Zombie){
targetable = !(this as Zombie).Invisible;
}
return targetable;
}
}
Insect, and Zombie all already derives from base class Creature, and FighterJet derives from class Machine However, not all Creature-s are targetable and do not use ITargetableUnit inteface.
Is there any workaround to solve the issue that I am facing?
Like everybody said you can't define behaviour for interfaces. Inherite the interface to the specific classes.
public interface ITargetableUnit
{
bool unitCanBeTargeted();
}
public class Insect : ITargetableUnit //you can add other interfaces here
{
public bool unitCanBeTarget()
{
return isFasterThanLight();
}
}
public class Ghost : ITargetableUnit
{
public bool unitCanBeTarget()
{
return !Flying();
}
}
public class Zombie : ItargetableUnit
{
public bool unitCanBeTarget()
{
return !Invisible();
}
}
Just for the record, you can actually do this (DONT!) but this isnt considered a good practice to make extensionmethods for code you have acces to. Mybirthname's solution is the way to go, this is just for demonstration.
public interface ITargetableUnit { }
public static class ITargetableUnitExtension
{
public static bool unitCanBeTargeted(this ITargetableUnit unit)
{
bool targetable = false;
Insect insect = unit as Insect;
if(insect != null)
return insect.isFasterThanLight();
FighterJet jet = unit as FighterJet;
if(jet != null)
return !jet.Flying;
Zombie zombie = unit as Zombie;
if(zombie != null)
return zombie.Invisible;
return false;
}
}
Maybe you want an abstract class and not an interface?
Interfaces define what methods a class provides. Abstract classes do this as well but can also take over some calculations for every child.
Please be aware that from a technical perspective an Insect can also be a Zombie.
Happy coding!
public abstract class TargetableUnit
{
//Returns whether the object of a class that implements this interface is targetable
public bool unitCanBeTargeted()
{
bool targetable = false;
if (this is Insect)
{
targetable = (this as Insect).isFasterThanLight();
}
else if (this is FighterJet)
{
targetable = !(this as FighterJet).Flying;
}
else if (this is Zombie)
{
targetable = !(this as Zombie).Invisible;
}
return targetable;
}
}
public class Insect : TargetableUnit
{
public bool isFasterThanLight()
{
return System.DateTime.UtcNow.Second == 0;
}
}
public class FighterJet : TargetableUnit
{
public bool Flying { get; set; }
}
public class Zombie : TargetableUnit
{
public bool Invisible { get; set; }
}

C# Loop Through Subclasses

Very new to C# so forgive me if this is a silly question.
If I have a base class called Validator, and a number of classes which inherit from this class such as validateFirstname, validateSecondname etc... is it possible to write a method which will loop through each of these subclasses and instantiate each?
Something along the lines of
public class loadValidators
{
public loadValidators()
{
foreach (subclass in class)
{
// instantiate class here
}
}
}
Any help is much appreciated as always.
Try this:
var validator_type = typeof (Validator);
var sub_validator_types =
validator_type
.Assembly
.DefinedTypes
.Where(x => validator_type.IsAssignableFrom(x) && x != validator_type)
.ToList();
foreach (var sub_validator_type in sub_validator_types)
{
Validator sub_validator = (Validator)Activator.CreateInstance(sub_validator_type);
}
This code assumes that all the sub classes live in the same assembly/project as the Validator class.
Also, it assumes that each of the subclasses have a public parameterless constructor.
Please note that I would not recommend this approach.
Instead you should do something like this to solve your problem (of modeling/using multiple validators):
public interface IValidator
{
bool Validate(SomeObject something);
}
public class FirstNameValidator : IValidator
{
public bool Validate(SomeObject something)
{
...
}
}
public class LastNameValidator : IValidator
{
public bool Validate(SomeObject something)
{
...
}
}
public class CompositeValidator : IValidator
{
private readonly IValidator[] m_Validators;
public CompositeValidator(params IValidator[] validators)
{
m_Validators = validators;
}
public bool Validate(SomeObject something)
{
foreach (IValidator validator in m_Validators)
{
if (!validator.Validate(something))
return false;
}
return true;
}
}
The CompositeValidator wraps multiple validators and knows how to validate objects using those validators.
You can use it like this:
var composite_validator = new CompositeValidator(new FirstNameValidator() , new LastNameValidator());
composite_validator.Validate(obj);

how to implement selective property-visibility in c#?

Can we make a property of a class visible to public , but can only be modified by some specific classes?
for example,
// this is the property holder
public class Child
{
public bool IsBeaten { get; set;}
}
// this is the modifier which can set the property of Child instance
public class Father
{
public void BeatChild(Child c)
{
c.IsBeaten = true; // should be no exception
}
}
// this is the observer which can get the property but cannot set.
public class Cat
{
// I want this method always return false.
public bool TryBeatChild(Child c)
{
try
{
c.IsBeaten = true;
return true;
}
catch (Exception)
{
return false;
}
}
// shoud be ok
public void WatchChild(Child c)
{
if( c.IsBeaten )
{
this.Laugh();
}
}
private void Laugh(){}
}
Child is a data class,
Parent is a class that can modify data,
Cat is a class that can only read data.
Is there any way to implement such access control using Property in C#?
Rather than exposing the inner state of the Child class you could provide a method instead:
class Child {
public bool IsBeaten { get; private set; }
public void Beat(Father beater) {
IsBeaten = true;
}
}
class Father {
public void BeatChild(Child child) {
child.Beat(this);
}
}
Then the cat can't beat your child:
class Cat {
public void BeatChild(Child child) {
child.Beat(this); // Does not compile!
}
}
If other people need to be able to beat the child, define an interface they can implement:
interface IChildBeater { }
Then have them implement it:
class Child {
public bool IsBeaten { get; private set; }
public void Beat(IChildBeater beater) {
IsBeaten = true;
}
}
class Mother : IChildBeater { ... }
class Father : IChildBeater { ... }
class BullyFromDownTheStreet : IChildBeater { ... }
This is usually achieved by using separate assemblies and the InternalsVisibleToAttribute. When you mark the set with internal classes within the current assembly will have access to it. By using that attribute, you can give specific other assemblies access to it. Remember by using Reflection it will still always be editable.

Call constant property on class like static?

I got an abstract base class
public class Base
{
public abstract String Info { get; }
}
and some children.
public class A : Base
{
public override String Info { get { return "A does ..."; } }
}
public class B : Base
{
public override String Info { get { return "B does ..."; } }
}
This is mere a constant but I want to make sure using Base that all classes implement it.
Now I sometimes do not have an object instance but want to access A.Info - this is not possible due it is a instance property.
Is there another way than implementing the same property on instance AND on static level? That would be feel like a duplicate violating DRY programming style.
NEW EDIT: I now see this two solutions:
public class Base
{
public abstract String ClassInfo { get; }
}
public class A : Base
{
public override String ClassInfo { get { return Info; } }
public static String Info { get { return "A does ..."; } }
}
public class B : Base
{
public override String ClassInfo { get { return Info; } }
public static String Info { get { return "In B we do ..."; } }
}
With this I can do with any object of type Base something like object.ClassInfo but also use the value in my factory hardcoded like if(A.Info) return new A(). But I have to implement two properties for the same information in every class.
On the other hand:
public class Base
{
public abstract String ClassInfo { get; }
public static String GetClassInfo<T>() where T : BaseControl, new()
{
T obj = new T();
return obj.ClassInfo;
}
}
public class A : Base
{
public override String ClassInfo { get { return "text A"; } }
}
public class B : Base
{
public override String ClassInfo { get { return "text B"; } }
}
Due to the abstract Base it is made sure that ClassInfo is always implemented. Calls with obj.ClassInfo and Base.GetClassInfo<A>() are okay. But with this every child of Base must have a default constructor without arguments and we loose performance with the unneccessary created instance.
Is there any other idea? Which one would you prefer and why?
If you need specific return results of your static properties, you're better of either
a) Instance properties
2) Attributes
In the example you've already given, you've got an instance of Base, which means you can just make the instance property virtual:
public class Base
{
public virtual string Info { get { return "From Base"; } }
}
public class A : Base
{
public override string Info { get { return "From A"; } }
}
If you wanted to go the attribute route, you define it as such:
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class InfoAttribute : Attribute
{
public InfoAttribute(string info) { this.Info = info; }
public string Info { get; private set; }
}
[InfoAttribute(Info = "From Base")]
public class Base
{
public string GetInfo()
{
var attr = GetType()
.GetCustomAttributes(typeof(InfoAttribute), true)
.FirstOrDefault();
return (attr == null) ? null : attr.Info;
}
}
[InfoAttribute(Info = "From A")]
public class A : Base { }
If you wanted to call it as a static function call, you could make this change:
public static string GetInfo(Base instance)
{
var attr = instance.GetType()
.GetCustomAttributes(typeof(InfoAttribute), true)
.FirstOrDefault();
return (attr == null) ? null : attr.Info;
}
And then call it as: Base.GetInfo(instance);. All in all, not very elegant!
This is not possible.
static members cannot be virtual or abstract.
You should make an abstract instance property.
Statics can't be overridden. If you truly want to do something like that, you'd want an instance property that is virtual in the base that gets overridden in the subclasses.
Does it compiled? I don't think so. Static cannot be marked as override, virtual or abstract.

Categories