To abstract, or not to abstract - c#

thanks in advance for reading this. I don’t fully understand how/when to use abstracts so I am trying to think about it each project I work on to see if it will all click some day Smile | :)
Also, the mix of accessibility levels (private, protected, internal) with keywords static, abstract, and override tend to leave me a little confused. How do I define this method/property/class....
It's not all a big mystery to me but some projects have me coding in circles when dealing with these topics.
With that said,
I have an application that reads an XML document and outputs text and image files. I’m also storing all of the information in a database. I have it working nicely.
The XML has a standard implementation with required fields and is used by multiple organizations to submit data to my app. All organizations should use (at least) the required nodes/elements that are outlined in the XML implementation guide.
So, I want to have a default data object type to be able to derive a specific organization’s data type for required elements. (If this object is going to be used, these are the fields that must be implemented).
If the org. just uses the default requirements, I can use the default object. If they use additional (optional) fields, I’ll have to create a new type inheriting the default type.
My first thought was to use and abstract class that had protected properties for my bare minimum requirements:
public abstract partial class AbstractDataObject
{
protected string DataObjectName;
protected DateTime? DataObjectDate;
etc...
}
Then, if the organization just uses the required elements of the node and no optional elements, I can use a “default” object.
internal partial class DefaultDataObject : AbstractDataObject
{
public new string DataObjectName { get; set; }
public new DateTime? DataObjectDate { get; set; }
etc...
}
But, if an organization uses optional fields of the required node, I can use a derived organization data object.
internal sealed partial class OranizationDataObject : AbstractDataObject
{
public new string DataObjectName { get; set; }
public new DateTime? DataObjectDate { get; set; }
etc...
//Optional fields used by this organization
public string DataObjectCode { get; set; }
etc...
}
Do I need the abstract class? It seems to me I can just have a DefaultDataObject (something like):
internal partial class DefaultDataObject
{
public virtual string DataObjectName { get; set; }
public virtual DateTime? DataObjectDate { get; set; }
etc...
}
And then:
internal sealed partial class OranizationDataObject : DefaultDataObject
{
public override string DataObjectName { get; set; }
public override DateTime? DataObjectDate { get; set; }
etc...
//Optional fields used by this organization
public string DataObjectCode { get; set; }
etc...
}
I’m just really trying to understand how to define these objects so I can reuse them per organization. Both ways seem to work, but I am hoping to understand how to define them properly.
Getting the XML into above objects:
public DefaultDataObject ExtractXmlData(XContainer root)
{
var myObject = (from t in root.
Elements("ElementA").Elements("ElementB")
select new DefaultDataObject()
{
DataObjectName = (String)t.Element("ChildElement1"),
DataObjectDate =
Program.TryParseDateTime((String)
t.Elements("ChildElement2")
.ElementAtOrDefault(0)
),
etc....
OR
public OranizationDataObject ExtractXmlData(XContainer root)
{
var myObject = (from t in root.
Elements("ElementA").Elements("ElementB")
select new OranizationDataObject()
{
DataObjectName = (String)t.Element("ChildElement1"),
DataObjectDate = Program.TryParseDateTime(
(String)t.Elements("ChildElement2")
.ElementAtOrDefault(0)),
DataObjectCode = (String)t.Element("ChildElement3"),
etc....
Again, thanks for reading. Don't forget to tip your wait staff....
Joe

First of all, your base class doesn't need to be abstract if it's a plain DTO class. If you don't have any functionality that needs to be implemented differently by derived classes, you can simply make it a plain base class which will hold common properties.
Next, there is no point in declaring properties in the base class (abstract in your case), if you are going to hide them (using the new keyword). You first code snippet of DefaultDataObject unnecessarily creates a bunch of new properties with the same name. Remove them completely - they are already defined in the base class.
[Edit] I didn't notice this initially, and #svick warned me, that your base class actually contained fields instead of properties, which makes me wonder why you needed to add the new keyword at all. I went over your code quickly and saw them as properties. In any case, you should never expose public fields - at least change them to auto-implemented properties by adding the { get; set; } block.
In other words, this would simply work:
// this doesn't need to be abstract.
// just put all the common stuff inside.
public class BaseDO
{
// as svick pointed out, these should also be properties.
// you should *never* expose public fields in your classes.
public string Name { get; set; }
public DateTime? Date { get; set; }
}
// don't use the new keyword to hide stuff.
// in most cases, you won't need that's behavior
public class DerivedDO : BaseDO
{
// no need to repeat those properties from above,
// only add **different ones**
public string Code { get; set; }
}
As a side note, but nevertheless important IMHO, you should simplify naming (and make it more clearer what your code does). There is no need to repeat "DataObject" in every property name, for example. But since your code is probably only a simplified version, it doesn't matter.
Lastly, have you heard of XmlSerializer? You don't need to traverse the XML elements manually. It is enough to call XmlSerializer to both serialize and deserialize your data.

Everything I need to know I learned from Sesame Street
Scrub your class design hard to make sure you've identified everything that is the same and different. Play computer, so to speak, with your classes and see how they do the same, different, or the same thing but in different ways.
What is the same, different, same but differently will likely change as you play computer.
Think in general terms of the two pillars of OO Classes. Polymorphism and Inheritance
As you do the above that is. Not so much in terms of C# implementation per se.
How things clump into same vs. different will help drive implementation
And it's all relative.
More of same default behavior? Perhaps a concrete base class instead of abstract.
More of same thing, but differently? Perhaps an abstract class instead of concrete base class.
A default way of doing x? Perhaps a virtual method.
Everyone does the same thing, but no two the same way? A delegate perhaps.
Implementation Suggestions
Make methods and fields protected as a default. Private does not get inherited. Designs change, stay flexible. If something just has to be private, fine.
virtual means you can change implementation in a sub class. It does not mean you must.
Folks seem to under-utilize delegates. They're super for polymorphic methods.
There is nothing wrong with public fields. What's the practical difference between a public field and a public auto-implemented property? Nothing. They both directly return (or set) the underlying value. So what's the point of even bothering with properties? If you want to publicly expose an underlying value differently than it's "natural" state. For example, returning a number in a specific format. And of course you can have different properties for the same field.
A Property can have a get without a set. Or vice versa. Also get and set can have different access levels. Often you'll see this as a public get and a protected (or private) set.

It depends on what the derived types will want to do. If they are going to use the default implementation and only expand on it somehow, then having the default class as the non-abstract base class is fine.
On the other hand, if they are most likely going to re-implement the functionality, you should have an abstract base class (or an interface) and a separate default class.
If you for some reason don't know which one is it, you can let the inheritors choose by having an abstract base class and leaving the default class unsealed.
Also, looking at your code, it seems you misunderstand what the various keywords do. Most of the time, you do not want to use new like this. What it does is to define another member with the same name, unrelated to the original one. Also, there's no reason to override something if you don't want to change it. So, if you expect that the derived classes won't have to reimplement the properties, you don't have to make them virtual at all.

An abstract class can already implement things that can be inherited
public abstract class DataObjectBase
{
public string DataObjectName { get; set; }
public DateTime? DataObjectDate { get; set; }
}
A concrete class can add new properties and methods
public class DerivedDataObject : DataObjectBase
{
public int NewProperty { get; set; }
}
The properties DataObjectName and DataObjectDate are already available in the new class, because they are automatically inherited from the base class.
If the abstract class defined an abstract member, however, you would have to implement it in the derived class.
Say the base class defines
public abstract void SomeMethod(string name);
The the derived class has to do this
public override void SomeMethod(string name)
{
...
}
If your base class does not have abstract members, it does not need to be abstract and can play the role of your default data object directly.
The keyword 'partial` is not needed here. It is only useful if you want to split one class into several pieces over several files.
The keyword new is wrong here. It is used to shadow an inherited member. This means that the inherited member will be hidden "behind" the new declaration. What you need, is to override. This does not hide a member, but provide an alternative implementation of the same member in the derived class.

Related

Is this candidate for abstract class

let's say that I want to collect in one place all common properties and behaviors for all sports. I was thinking to use SportBase as abstract class for this purpose but I'm not sure. I'm trying to understand the differences between Abstract vs Interface usage on this example.
Every sport should have following properties
DateTime Started;
DateTime Ended;
string Name;
What if I declare these properties like integers and later on I decide to use Game object as separated entity like Game StartGame. I do not see clearly which approach to use with high level of abstraction to reduce pain on later modification (this modification can have adding new properties, new behaviors, etc.)
Thanks
if you only have properties and empty methods an interface might be your better choice. if you have some actual code then abstract class is your only option. also remember that you can inherit only one abstract class but implement multiple interfaces.
You can use an interface to provide a contract to code to.
public interface ISportsEvent
{
DateTime Start { get; set; }
DateTime End { get; set; }
string Name { get; set; }
}
but that doesn't give you a reusable implementation
As a general rule you should prefer composition over inheritance.
So its often better to do something like this
public interface EventDetails
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
public string Name { get; set; }
}
public class SportingEvent
{
public EventDetails Details {get;set;}
}
now this is a bit rough but you can see what I'm getting at.
No, I wouldn't do that. You'll end up creating an abstract God class, which has way to many responsabilities.
I personally would probably make it an abstract class, since not only will your sports share some fields, but they might share some logic too.
Interfaces aren't for seperating out duplicate code, but they're purely for polymorphism.
All an interface does is guarantee that your class will act a certain way. If you plan on putting logic in your base class than you want an abstract class.

Where should properties reside when modeling OOP? Small example included

I'm looking to learn how to use interfaces and base classes effectively. I'm not exactly sure where to put common properties? Do only behaviors belong in an interface? If properties such as: Color and MinSpeed shouldn't go in the interface, where should they live? In an abstract class?
public interface IVehicle
{
void Speed();
void Clean();
void Stop();
}
public class Bmw : IVehicle
{
// Because these pertain to every vehicle no matter of maker,
// should these propertes go in the interface? Or in an abstract class?
public string Color { get; set; }
public int MinSpeed { get; set; }
#region IVehicle Members
public void Speed()
{
}
public void Clean()
{
}
public void Stop()
{
}
#endregion
}
Interfaces can be thought of as a contract that must be satisfied by any implementing class. Use it if you want to guarentee that all classes do the same thing—satisfy the same API—but you don't care how they do it. If properties are a part of that API, then by all means include them in your interface.
From your example above, if you want all cars to be guaranteed to have a color and minSpeed, then those properties belong in the interface. If those properties are specific to BMWs alone, then they belong in the BMW class. If those properties belong to some classes but not others, you could create a new interface extending the original one:
public interface IVehicleWithColorAndMinSpeed : IVehicle
{
string Color { get; set; }
int MinSpeed { get; set; }
}
(just don't get carried away with this)
Abstract classes are similar, but allow you to provide a default implementation for your sub classes.
Abstract classes tend to be easier to version, since you can add something new to your API, and provide a default implementation that your existing subclasses will automatically pick up; adding something to an interface immediately breaks all existing classes which implement that interface.
The 'right' answer is entirely dependent on your domain model. What is the problem you're trying to solve? There is no 'right' answer other than the one which solves the particular problem at hand with the greatest:
understandability
maintainability
brevity
isolation
performance
You can probably consider most of those properties to be in order of importance, but they mean different things to different people and there's probably a lot of debate implied there too.
Can you tell us any more about the particular application you imagine these classes to serve?

Should I declare my abstract class's attributes with get; set;?

I'm making a little program that will crawl my hard drive and present a list of file found in a given drive.
My idea is to have a base File class, and implement Picture.cs, Video.cs and Document.cs classes inherited from the File.cs class.
Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SharpLibrary_MediaManager
{
public abstract class File
{
public string name;
public string fileType;
public int size;
public DateTime creationDate;
public DateTime modificationDate;
}
}
Should I declare the short hand code for each attribute like this:
public string name { get; set; }
Any guidance will be helpful. Thank you. :)
Edit:
I mean literally replacing this line:
public string name;
with this line:
public string name { get; set; }
First, "attributes" is not the correct terminolgy here. When you declare a member of a class that has get and/or set defined (formally known as "accessors"), you are defining a property. Properties are a convenient way to expose values of private fields because you can add logic to the getting and setting mechanims.
Second, when you declare a member name as you've done via
public string name { get; set; }
the compiler will expand that into the following:
private string _name;
public string name {
get {
return _name;
}
set {
_name = value;
}
}
That is, the compiler will automatically create a backing field for you and define the accessors. These are called "automatic properties" (for the people)1.
Third, you should never2 publically expose fields. So, if you want to expose the string name as part of your public interface it is better to do it as a property. First, it provides better encapsulation. Second, it can be declared virtual and overridden in dervied classes. Third, you can have custom logic. Fourth, you can have different levels of accessibly between the reading and writing mechanisms on properties but you can not on a field.
Fourth, per accepted naming convetions, public properties should be named with CamelCase so that you should prefer Name instead of name.
1: Sorry, bad joke that I've been waiting a long time to make.
2: Almost never.
You're not describing a short hand syntax for a single item but rather 2 completely different types of members. The get/set version creates a C# Property while the non-get/set version creates a field.
// field
public string name;
// property
public string name {get; set;}
So what you're actually asking here is whether or not you should expose name as a field or a property. The answer is almost certainly property.
If your looking to have these properties, which is what adding the { get; set; } will make the variables, then you should declare the set; part of the property as protected.
So it becomes:
public string name { get; protected set; }
The advantage of this is that you are guaranteeing that the property can only be set by either the base class, or any class that inherits the base class.
As others have suggested, following the C# naming conventions is a good idea and also using properties are highly recommended.
Just to be clear, attributes are means to do declarative programming. They are used to decorate methods, classes, etc. msdn link
If you're asking whether to expose properties rather than public fields, then the answer is Yes.
You should also use PascalCase for the property names rather than camelCase:
public string Name { get; set; }
public string FileType { get; set; }
// etc
As Luke says, all things being equal, properties are preferred to fields.
In addition you may want to change the casing of your fields to match standard C# naming conventions.
Lastly, you might want to avoid the "File" name for your class as you'll probably be using the System.IO namespace which also has a File class. Also, System.IO.FileInfo may already include many of the properties you are planning on creating -- there's no point reinventing the wheel.
I believe another advantage of properties over normal public fields will be ability to override them in the derived class.
class Base
{
public virtual int X
{
get
{
Console.Write("Base GET");
return 10;
}
set
{
Console.Write("Base SET");
}
}
}
class Derived : Base
{
public override int X
{
get
{
Console.Write("Derived GET");
return 10;
}
set
{
Console.Write("Derived SET");
}
}
}
Another useful trick that is applicable while using properties is the ability to modify the modifier of the the derived Properties like changing from Public access to Protected.
Hence in many ways its better to use properties in base class to derive.

How to hide an inherited property in a class without modifying the inherited class (base class)?

If i have the following code example:
public class ClassBase
{
public int ID { get; set; }
public string Name { get; set; }
}
public class ClassA : ClassBase
{
public int JustNumber { get; set; }
public ClassA()
{
this.ID = 0;
this.Name = string.Empty;
this.JustNumber = string.Empty;
}
}
What should I do to hide the property Name (Don't shown as a member of ClassA members) without modifying ClassBase ?
I smell a code smell here. It is my opinion that you should only inherit a base class if you're implementing all of the functionality of that base class. What you're doing doesn't really represent object oriented principles properly. Thus, if you want to inherit from your base, you should be implementing Name, otherwise you've got your inheritance the wrong way around. Your class A should be your base class and your current base class should inherit from A if that's what you want, not the other way around.
However, not to stray too far from the direct question. If you did want to flout "the rules" and want to continue on the path you've chosen - here's how you can go about it:
The convention is to implement the property but throw a NotImplementedException when that property is called - although, I don't like that either. But that's my personal opinion and it doesn't change the fact that this convention still stands.
If you're attempting to obsolete the property (and it's declared in the base class as virtual), then you could either use the Obsolete attribute on it:
[Obsolete("This property has been deprecated and should no longer be used.", true)]
public override string Name
{
get
{
return base.Name;
}
set
{
base.Name = value;
}
}
(Edit: As Brian pointed out in the comments, the second parameter of the attribute will cause a compiler error if someone references the Name property, thus they won't be able to use it even though you've implemented it in derived class.)
Or as I mentioned use NotImplementedException:
public override string Name
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
However, if the property isn't declared as virtual, then you can use the new keyword to replace it:
public new string Name
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
You can still use the Obsolete attribute in the same manner as if the method was overridden, or you can throw the NotImplementedException, whichever you choose. I would probably use:
[Obsolete("Don't use this", true)]
public override string Name { get; set; }
or:
[Obsolete("Don't use this", true)]
public new string Name { get; set; }
Depending on whether or not it was declared as virtual in the base class.
While technically the property won't be hidden, one way to strongly discourage its use is to put attributes on it like these:
[Browsable(false)]
[Bindable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[EditorBrowsable(EditorBrowsableState.Never)]
This is what System.Windows.Forms does for controls that have properties that don't fit. The Text property, for instance, is on Control, but it doesn't make sense on every class that inherits from Control. So in MonthCalendar, for instance, the Text property appears like this (per the online reference source):
[Browsable(false),
EditorBrowsable(EditorBrowsableState.Never),
Bindable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Text {
get { return base.Text; }
set { base.Text = value; }
}
Browsable - whether the member shows up in the Properties window
EditorBrowsable - whether the member shows up in the Intellisense dropdown
EditorBrowsable(false) won't prevent you from typing the property, and if you use the property, your project will still compile. But since the property doesn't appear in Intellisense, it won't be as obvious that you can use it.
Just hide it
public class ClassBase
{
public int ID { get; set; }
public string Name { get; set; }
}
public class ClassA : ClassBase
{
public int JustNumber { get; set; }
private new string Name { get { return base.Name; } set { base.Name = value; } }
public ClassA()
{
this.ID = 0;
this.Name = string.Empty;
this.JustNumber = 0;
}
}
Note: Name will still be a public member of ClassBase, given the constraint of not changing the base class there is no way to stop that.
Why force inheritance when it's not necessary?
I think the proper way of doing it is by doing has-a instead of a is-a.
public class ClassBase
{
public int ID { get; set; }
public string Name { get; set; }
}
public class ClassA
{
private ClassBase _base;
public int ID { get { return this._base.ID; } }
public string JustNumber { get; set; }
public ClassA()
{
this._base = new ClassBase();
this._base.ID = 0;
this._base.Name = string.Empty;
this.JustNumber = string.Empty;
}
}
I don’t think a lot of the people replying here understand inheritance at all. There is a need to inherit from a base class and hide its once public var’s and functions. Example, lets say you have a basic engine and you want to make a new engine that is supercharged. Well, 99% of the engine you will use but you will tweak a bit of its functionality to make it run much better and yet still there is some functionality that should only be shown to the modifications made, not the end user. Because we all know that every class MS puts out doesn’t really ever need any modifications.
Besides using the new to simply override the functionality it is one of the things that Microsoft in their infinite wis….. oh, I mean mistakes considered a tool not worthwhile anymore.
The best way to accomplish this now is multi-level inheritance.
public class classA
{
}
public class B : A
{}
public class C : B
{}
Class B does all your work and class C exposes what you need exposed.
You can't, that's the whole point of inheritance: the subclass must offer all methods and properties of the base class.
You could change the implementation to throw an exception when the property is called (if it were virtual)...
I completely agree that properties should not be removed from base classes, but sometimes a derived class might have a different more appropriate way to enter the values. In my case, for example, I am inheriting from ItemsControl. As we all know, ItemsControl has the ItemsSource property, but I want my control to merge data from 2 sources (for example, Person and Location). If I were to have the user enter the data using ItemsSource, I would need to separate and then recombine the values, so I created 2 properties to enter the data. But back to the original question, this leaves the ItemsSource, which I do not want the user to use because I am "replacing" it with my own properties. I like the Browsable and EditorBrowsable ideas, but it still does not prevent the user from using it. The basic point here is that inheritance should keep MOST of the properties, but when there is a large complex class (especially ones where you cannot modify the original code), rewriting everything would be very inefficient.
You can use Browsable(false)
[Browsable( false )]
public override string Name
{
get { return base.Name; }
set { base.Name= value; }
}
I think it is bad design if you have to do this, especially if you are able to design the code from the ground up.
Why?
Good design is to let the base-class share common properties that a certain concept has (virtual or real). Example: System.IO.Stream in C#.
Further down the lane bad design will increase the cost for maintenance and make implementation harder and harder. Avoid this as much as possible!
Basic rules which I use:
Minimize the number of properties and methods in the base-class. If you do not expect to use some properties or methods in a class that inherits the base class; do not put it in the baseclass then. If you are in the developmentstage of a project; always go back to the drawing-board now an then to check the design because things change! Redesign when needed. When your project is live the costs for changing things later in the design will go up!
If you are using a baseclass implemented by a 3:rd party, consider "go up" one level instead of "overriding" with "NotImplementedException" or such. If there is no other level, consider design the code from scratch.
Always consider to seal classes you do not want anyone to be able to inherit it. It forces coders to "go up one level" in the "inheritance- hierarchy" and thus "loose ends" like "NotImplementedException" can be avoided.
I know that the question is old, but what you can do is override the PostFilterProperties like this:
protected override void PostFilterProperties(System.Collections.IDictionary properties)
{
properties.Remove("AccessibleDescription");
properties.Remove("AccessibleName");
properties.Remove("AccessibleRole");
properties.Remove("BackgroundImage");
properties.Remove("BackgroundImageLayout");
properties.Remove("BorderStyle");
properties.Remove("Cursor");
properties.Remove("RightToLeft");
properties.Remove("UseWaitCursor");
properties.Remove("AllowDrop");
properties.Remove("AutoValidate");
properties.Remove("ContextMenuStrip");
properties.Remove("Enabled");
properties.Remove("ImeMode");
//properties.Remove("TabIndex"); // Don't remove this one or the designer will break
properties.Remove("TabStop");
//properties.Remove("Visible");
properties.Remove("ApplicationSettings");
properties.Remove("DataBindings");
properties.Remove("Tag");
properties.Remove("GenerateMember");
properties.Remove("Locked");
//properties.Remove("Modifiers");
properties.Remove("CausesValidation");
properties.Remove("Anchor");
properties.Remove("AutoSize");
properties.Remove("AutoSizeMode");
//properties.Remove("Location");
properties.Remove("Dock");
properties.Remove("Margin");
properties.Remove("MaximumSize");
properties.Remove("MinimumSize");
properties.Remove("Padding");
//properties.Remove("Size");
properties.Remove("DockPadding");
properties.Remove("AutoScrollMargin");
properties.Remove("AutoScrollMinSize");
properties.Remove("AutoScroll");
properties.Remove("ForeColor");
//properties.Remove("BackColor");
properties.Remove("Text");
//properties.Remove("Font");
}

instantiating a child from a parent type

I have a base type which stores information about a question in a question pool for a system which generates practice question sets to help people study for multiple choice tests. The only information that is stored in it are the answers, the prompt and question number. When I create a practice test, I need to augment the type with some properties to store the answer submitted (the test can be taken in parts), and so I created the following classes:
public class MultipleChoiceQuestion
{
public Int32 Number { get; internal set; }
public String Prompt { get; internal set; }
public MultipleChoiceAnswer[] Choices { get; internal set; }
// constructors, etc...
}
public class PracticeTestQuestion : MultipleChoiceQuestion
{
public MultipleChoiceAnswer AnswerSelected { get; set; }
// is this right?
public PracticeTestQuestion(MultipleChoiceQuestion question)
{
...
}
}
Originally I had the MultipleChoiceQuestion as just a member of PracticeTestQuestion, but it added a lot of extra dots in my property accessors, and so I changed it to inherit the class as listed above. Currently I am assigning all of the properties line for line in the constructor, and but it feels sort of cumbersome, and I was wondering if there is a better way.
The C# compiler doesn't like upsizing types for good reasons, so my question is what is the best way to go about instantiating my PracticeTestQuestions from their MultipleChoiceQuestion base types?
I would add a constructor to MultipleChoiceQuestion that takes another MultipleChoiceQuestion. If necessary it can assign each of the properties in the constructor, but that's more appropriate, since it has the knowledge of its own properties.
Then in PracticeTestQuestion, you can just do:
public PracticeTestQuestion(MultipleChoiceQuestion question) : base(question) { }
and be done with it.
My first gut reaction is to use a factory to create questions. You ask the factory for a MCQ or a PTQ and it creates the right one.
This is also more extensible to essay questions, true false, etc.

Categories

Resources