The best way to use child classes and methods - c#

Have some newbie questions.
I have 6 classes:
public class MainSettingsClass
{
int a;
int b;
}
public class SubSettingsClass_1 : MainSettingsClass
{
int c;
}
public class SubSettingsClass_2 : MainSettingsClass
{
int d;
}
public class ParentClass
{
public MainSettingsClass settings;
}
public class ChildClass_1 : ParentClass
{
}
public class ChildClass_2 : ParentClass
{
}
Now the questions. ChildClass_1 with SubSettingsClass_1 and ChildClass_2 with SubSettingsClass_1
ChildClass_1 firstClassVar = new ChildClass_1();
ChildClass_2 secondClassVar = new ChildClass_2();
SubSettingsClass_1 firstClassSettings = new SubSettingsClass_1();
SubSettingsClass_2 secondClassSettings = new SubSettingsClass_2();
firstClassVar.settings = (MainSettingsClass)firstClassSettings;
secondClassVar.settings = (MainSettingsClass)secondClassSettings;
The main thing that if i need get "c" variable using "firstClassVar.settings" i need everytime write:
((firstClassSettings)firstClassVar.settings).c
Is it right way to access variables?
Or there is a better ways exists?
Is this code corresponds programming rules? Or its not correct?
Sorry for bad english.

Is that the "right" way to access the c variable? No. If you have to downcast, at least check it first:
firstClassSettings derivedSettings = firstClassVar.settings as firstClassSettings;
if (derivedSettings != nulL)
{
//Do whatever with derivedSettings.c
}
There's a better way :) Its called polymorphism. Your classes are super general, so its hard to say exactly how your design should look, but your main class should have some method that the derived classes override to get the custom behavior.
Downcasting is a huge code-smell. Sometimes there is no way around it (especially in legacy code, or in certain Object overrides and WPF interfaces) but, you should avoid it if at all possible. Doubly so in your own objects/code.

What you have is technically fine, although there's a few somewhat problematic aspects. First, there's no need to cast to MainSettingsClass. Since both SubSettingsClass_1 and SubSettingsClass_2 inherit from MainSettingsClass, ParentClass, and all derivatives thereof, will accept either as the value for a field defined as being of type MainSettingsClass.
Second, fields (of which settings is one) aren't typically made public. Properties, which have defined getters and setters are generally your interface to data on a object.
Third, settings here is a dependency, and as such, should really be injected via the constructor of the class. Something like:
public class ParentClass
{
protected MainSettingsClass settings;
public ParentClass(MainSettingsClass settings)
{
this.settings = settings;
}
}
UPDATE
One more thing I just thought about that would be beneficial for you to know. Keep in mind that by using a least common denominator like MainSettingsClass, you lose the ability to work with specific members of the more specific derived classes SubSettingsClass_1 and SubSettingsClass_2. However, generics can be used to give you a bit more flexibility:
public class ParentClass<TSettings>
where TSettings : MainSettingsClass
{
protected TSettings settings;
public ParentClass(TSettings settings)
{
this.settings = settings;
}
}
public class ChildClass_1 : ParentClass<SubSettingsClass_1>
{
...
}
public class ChildClass_2 : ParentClass<SubSettingsClass_2>
{
...
}
With that, you can now work with c in ChildClass_1 and d in ChildClass_2 because the type of your settings field will be SubSettingsClass_1 and SubSettingsClass_2, respectively.

Related

What is a good way to deal with multiple object types in the same form?

I have an abstract base class and two derived classes. The base class contains 6 properties which all can be maintained on a form.
The two derived classed both have 1 extra property. Those two properties can also be maintained on the same form.
In my form I have now code like this:
btnSomething.visible = (myObject is DerivedA);
pnlPanel.visible = !(myObject is DerivedA);
if(myObject is DerivedA)
myBindingSource.DataSource = myObject as DerivedA
mySecondBindingSource = myObject;
I am not very happy with this approach, it smells. So my question is, what is a neat/good way to make this more OO? Because it is possibly that in the future DerivedC comes in...
I think this approach breaks the OCP principle (and probably other principles)
You can use polymorphism and inheritance here:
Define an interface
interface ICommonFeatures
{
bool ContainsFoo {get;}
//yak-yak
}
Then your derived classes implement it
class DerivedA: ICommonFeatures
{
bool ContainsFoo {get {return true;}}
//so-and-so
}
class DerivedB: ICommonFeatures
{
bool ContainsFoo {get {return false;}}
//this-and-that
}
And when you use it, you deal only with the interface
ICommonFeatures foo = new DerivedB();
btnSomething.visible = foo.ContainsFoo;
pnlPanel.visible = foo.Prop2;
myBindingSource.DataSource = foo.CurrentDataSource
A crazy idea would be make the UI extensible.
You could make a form implement a base form.
Then in the derived form class you would only insert the missing controls and behavior for the its model class.
In the derived model class or library you could have some sort binding to the correct form.
A good approach for this would be follow some MVP principles.
Hope it helps you somehow..
I would declare an abstract boolean method/property for each control that need to behave according to the underlying type.
For instance
// to handle pnlPanel.visible = !(myObject is DerivedA);
abstract bool SupportsPanel{get;}
As for your binding sources, I would also provide some virtual BindingSource and SecondBindingSource properties.
Maybe something like (purely an example)
public abstract class BaseClass
{
// All your exising class declaration here
public virtual object BindingSource
{
get
{
// By default, a BaseClass is not valid as a binding source
return null;
}
}
public virtual object SecondBindingSource
{
get
{
// By default, a BaseClass is a valid Second Binding source
return this;
}
}
}
public class DerivedA : BaseClass
{
// All your exising class implementation here
public override object BindingSource
{
get
{
// For DerivedA, the data sourse is itself.
// other classes might have their own implementations.
return this;
}
}
// No need to override SecondBindingSource as the BaseClass one works as expected.
}
So, your code could stop caring about the object type and look like:
myBindingSource.DataSource = myObject.BindingSource;
mySecondBindingSource = myObject.SecondBindingSource;
Hope this helps.

Methods for Lazy Initialization with properties

I'm currently altering a widely used class to move as much of the expensive initialization from the class constructor into Lazy Initialized properties. Below is an example (in c#):
Before:
public class ClassA
{
public readonly ClassB B;
public void ClassA()
{
B = new ClassB();
}
}
After:
public class ClassA
{
private ClassB _b;
public ClassB B
{
get
{
if (_b == null)
{
_b = new ClassB();
}
return _b;
}
}
}
There are a fair few more of these properties in the class I'm altering, and some are not used in certain contexts (hence the Laziness), but if they are used they're likely to be called repeatedly.
Unfortunately, the properties are often also used inside the class. This means there is a potential for the private variable (_b) to be used directly by a method without it being initialized.
Is there a way to make only the public property (B) available inside the class, or even an alternative method with the same initialized-when-needed?
This is reposted from Programmers (not subjective enough apparently):
https://softwareengineering.stackexchange.com/questions/34270/best-methods-for-lazy-initialization-with-properties
Well, my recommended solution would be to tell your coworker to use the property, not the field. But you could idiot-proof it to some degree like this:
public class ClassA
{
private Lazy<ClassB> _b = new Lazy<ClassB>(() => new ClassB());
public ClassB B
{
get
{
return _b.Value;
}
}
}
Now it's pretty hard to screw up.
You could consider pushing the lazy properties into a base class to avoid direct access to the backing variable. Not ideal I know. I've always thought this was something lacking in C# i.e. direct support for lazy properties.
#chibacity posted (and subsequently) deleted [and later undeleted :P] an alternative option using an abstract base class. While it may not be ideal in terms of code distribution it does provide a nice encapsulation removing a lot of code clutter making for a cleaner and more succinct ClassA. For instance, you could consider combining the techniques to achieve both goals:
public class ClassB { /* Class to be lazily instantiated */ }
public abstract class BaseA
{
private Lazy<ClassB> _b = new Lazy<ClassB>(() => new ClassB());
public virtual ClassB B { get { return _b.Value; } }
}
public class ClassA : BaseA
{
public override ClassB B { get { return base.B; } }
}
At first glance, it seems like this is more long winded, but when you consider that ClassA which is the class you would be working in and with, this now means that all your references are going through the same property - there is no extraneous unnecessary field causing potential confusion, there's no bypassing the property to reference _b directly and there's no need to tell your coworker which to use... there's only one.
Not saying this is the right way to do this or that this is a pattern that should or shouldn't be followed, I'm just pointing out the advantages of what #chibacity suggested that may otherwise go unnoticed.
It would be nice if you could have implicit lazy loaded properties without having to refer to B.Value... for instance:
[Lazy]
public ClassB B { get; }
or for objects without parameterless constructors
[Lazy(() => new ClassB("Hello", "World"))]
public ClassB B { get; }
or perhaps as #chibacity suggested in a comment
public ClassB B { lazyget; }
or
public ClassB B { lazyget : new ClassB(); }
Alas, I don't think any of these are currently available solutions in any form...

How to create a constructor that is only usable by a specific class. (C++ Friend equivalent in c#)

As far as I know, in C#, there is no support for the "friend" key word as in C++. Is there an alternative way to design a class that could achieve this same end result without resorting to the un-available "friend" key-word?
For those who don't already know, the Friend key word allows the programmer to specify that a member of class "X" can be accessed and used only by class "Y". But to any other class the member appears private so they cannot be accessed. Class "Y" does not have to inherit from class "X".
No, there is no way to do that in C#.
One common workaround is to based the object for which you want to hide the constructor on an interface. You can then use the other object to construct a private, nested class implementing that interface, and return it via a Factory. This prevents the outside world from constructing your object directly, since they only ever see and interact with the interface.
public interface IMyObject
{
void DoSomething();
}
public class MyFriendClass
{
IMyObject GetObject() { return new MyObject(); }
class MyObject : IMyObject
{
public void DoSomething() { // ... Do something here
}
}
}
This is how I solved it. I'm not sure if it's the "right" way to do it, but it required minimal effort:
public abstract class X
{
// "friend" member
protected X()
{
}
// a bunch of stuff that I didn't feel like shadowing in an interface
}
public class Y
{
private X _x;
public Y()
{
_x = new ConstructibleX();
}
public X GetX()
{
return _x;
}
private class ConstructibleX : X
{
public ConstructibleX()
: base()
{}
}
}
No. The closest you have is an internal constructor, or a private constructor and a separate factory method (probably internal, so you haven't saved much).
What about just having it explicity implement an interface that is only visible to a certain class?
Something like:
public void IFreindOfX.Foo() //This is a method in the class that's a 'friend' to class X.
{
/* Do Stuff */
}
and then make sure IFriendOfX is visible to class X. In your X class you'd call the method by first casting X to IFriendOfX then calling Foo(). Another advantage is that is is fairly self documenting... that is, it's pretty close to having the friend keyword itself.
What about creating a private class? This does exactly what you seem to be describing. A member of class X can be accessed and used only by class Y, and to any other class it appears private, since, well, it is private:
public class Y
{
private class X { }
private X Friend;
public Y()
{
Friend = new X();
}
}
As far as I know, the Internal keyword is the closest thing in .NET. This question will shed more light on Internal: Internal in C#
The only thing I can think of that would even come close would be protected internal but that does not restrict it to a specific class. The only friending I'm aware of in c# is to make a friend assembly. Still does not restrict to a specific class.
The only thing I could think of to try and do it would be to do something like the following:
public class A
{
public A() {}
protected internal A(B b) {}
}
public class B
{
A myVersion;
public B()
{
myVersion = A(this);
}
}
The only other way I could think of would be to do some sort of Constructor Injection using reflection that is done inside of your friend class. The injection mechanism would allow you to limit it to what you want but could be very cumbersome. Take a look at something like Spring.Net for some injection capabilities.
As a workaround, I suppose you could create a conditional in your constructor that uses reflection.
For example, if Class1's constructor must be called by Class2:
public Class1()
{
string callingClass = new StackFrame(1).GetMethod().DeclaringType.Name;
if (callingClass != "Class2")
{
throw new ApplicationException(
string.Concat("Class1 constructor can not be called by ",
callingClass, "."));
}
}
EDIT:
Please note that I would never actually do this in "real" code. Technically it works, but it's pretty nasty. I just thought it was creative. :)
You can access private members/methods using Reflection.
Since it's got the design tag, I never particularly liked the friend keyword. It pierces encapsulation and that always felt dirty to me.
This has a bit of a smell. There are other plenty of other ways to achieve implementation hiding in C#. Limiting construction to only specific classes does not achieve all that much.
Could you please provide more information as to the purpose of this requirement? As already answered, internal is the closest match for limiting accessibility to the class. There are ways to build on top of that depending on the purpose.

Deriving static members

I have a base class that has a private static member:
class Base
{
private static Base m_instance = new Base();
public static Base Instance
{
get { return m_instance; }
}
}
And I want to derive multiple classes from this:
class DerivedA : Base {}
class DerivedB : Base {}
class DerivedC : Base {}
However, at this point calling DerivedA::Instance will return the same exact object as will DerivedB::Instance and DerivedC::Instance. I can solve this by declaring the instance in the derived class, but then every single derived class will need to do that and that just seems like it should be unneccessary. So is there any way to put all this in the base class? Could a design pattern be applied?
There's one really icky way of doing this:
class Base
{
// Put common stuff in here...
}
class Base<T> : Base where T : Base<T>, new()
{
private static T m_instance = new T();
public static T Instance { get { return m_instance; } }
}
class DerivedA : Base<DerivedA> {}
class DerivedB : Base<DerivedB> {}
class DerivedC : Base<DerivedC> {}
This works because there's one static variable per constructed type - e.g. List<string> is a different type to List<int> and so would have separate static variables.
I've taken the opportunity of making it an instance of the derived class as well - I don't know whether that's what you want or not, but I thought I'd at least make it available for you :)
In general though, this is a nasty thing to do. Static variables aren't really designed for this kind of use - I've just abused a feature of generics to get "sort of" the behaviour you asked for.
Also note that Base<DerivedA>.Instance will return the same result as DerivedA.Instance - the property/variable don't "know" that you're using DerivedA.Instance. I don't know whether or not that's important to you.
With the extra non-generic class, you can write:
Base t = DerivedA.Instance;
t = DerivedB.Instance;
If you don't need that, take it out :)
Static methods does not support polymorphism, therefore, such a thing is not possible.
Fundamentally, the Instance property has no idea how you're using it. And a single implementation of it will exist, as it's static. If you really wanted to do this, this "not recommended" solution is available (I got the idea from Jon's solution):
private static Dictionary<Type, Base> instances = new Dictionary<Type, Base>();
public static T GetInstance<T>() where T : Base, new() {
Type ty = typeof(T);
T x;
if (instances.TryGetValue(ty, out x)) return x;
x = new T();
instances[ty] = x;
return x;
}
Short answer: not that I'm aware of. Static members are always nonvirtual and do not readily support polymorphism.
However, you should also ask yourself why you are doing this. Normally, static members are shared resources that every instance of that class (including the derived classes) will find useful. However, when you make a static instance, you are usually building towards a singleton pattern. In this case, you usually want to seal the class so you can't have derived classes, thus rendering the entire point moot. Thus, you should really be analyzing why you are wanting to do this and solve that problem instead.

Implementing friend (available in C++) functionality in C#

Ok, let's leave the debate of whether friendship breaks encapsulation, and actually try elegantly come up with a coherent design. It is a two fold function:
1) General question on how to implement:
public class A
{
friend class B;
}
2) Why do I need this functionality? Some of my classes implement ISerializable interface. However, I want to make ISerializable methods protected in the Derived class so that I don't expose them to a client (as well as in the documentation). However, internal classes should be able to access them. What is the General way to solve this problem in C#?
Note: I am using friendship as defined in the current C++ standard.
Thanks
C# has the internal keyword, so that other types in the same assembly see the types marked internal. Additionally, you can add attributes to the assembly to allow types outside of the assembly to see that assembly's internal members.
If the classes are in the same assembly you can use internal. If they're in different assemblies you can use the friend assembly attribute.
Leaving the InternalsVisibleTo stuff to one side, you only have two choices when it comes to implementing interfaces:
Implement them with public methods
Implement them using explicit interface implementation
In both cases anyone can call the methods, but using explicit interface implementation you can only call the methods "via" an interface expression (e.g. you could cast a variable of the actual type to the ISerializable).
There's no such concept as "internally" implementing an interface.
internal members are public within the current .dll and private externally. Additionally, you can expose them to external .dll's by using the InternalsVisibleTo attribute.
I have several solutions, that all revolve around using a private singleton instance as a "key" to prove that the caller is who they say they are.
Solution 1: friend class is a singleton
public class A
{
private underwear myUnderwear;
public ChangeUnderwear(B friend, underwear newUnderwear)
{
if (friend == null) return;
myUnderwear = newUnderwear
}
}
public sealed class B
{
private B() {};
private B inst;
private MessWithA(A a)
{
a.ChangeUnderwear(this, new Thong());
}
}
Does anyone see any flaw there? That technique would work for when you have a Foo class and a FooManager singleton.
Solution 2:
If the friend is not a singleton, I guess you could use the same idea of hiding construction and hiding all instances:
interface IB
{ ... }
public sealed class B : IB
{
private B() {};
public IB CreateB()
{
return (IB)new B();
}
private MessWithA(A a)
{
a.ChangeUnderwear(this, new Thong());
}
}
But now you now you need some way to prevent an enemy from simply casting IB to a B, and then impersonating a B to access A's friend only members. Any ideas?
Solution 3: the singleton class lets it's instance be owned by the first caller who requests it. The friend class tries to grab the instance on startup, and throws a tantrum if someone else grabs it first
public class A
{
private underwear myUnderwear;
public ChangeUnderwear(B.IdCard friend, underwear newUnderwear)
{
if (friend == null) return;
myUnderwear = newUnderwear
}
}
public class B
{
public sealed class IdCard
{
private IdCard() {};
private static bool created = false;
public IDCard GetId()
{
if (created) throw new Exception("Why are two people asking for the same ID?!?");
created = true;
return new IDCard();
}
}
private static IdCard id;
static B()
{
id = IDCard.CreateId();
if (id == false) throw new Tantrum("Panic: Someone stole my ID card before I could grab it");
}
private void MessWithA(A a)
{
a.ChangeUnderwear(id, new Thong());
}
}

Categories

Resources