I have a web service that will return a List where Person is a DTO. Is there any reason I shouldn't define Person like:
public class Person {
public string Name;
public string Email;
}
instead of
public class Person {
private string _name;
public string Name {
get {
return _name;
}
set {
_name = value;
}
}
}
The second version is more verbose, and I can't see any reason public instance variables could be a problem here. Any reason it could be?
Properties are preferred over fields to support
binding; fields cannot be bound
polymorphism; you can't do public virtual string Name;
You can use automatic properties to reduce the verbosity
public class Person {
public string Name { get; set; }
public string Email { get; set; }
}
In general - this is a design decision - see: http://forums.asp.net/t/1233827.aspx
But the DTO implementation is slightly different. Since this is just a DTO and there is no behavior with no set/get property specific implementation the usage you could just as well use the less verbose method. Any implementation change would not require client recompiles since they will be serialized the same way in either case via a service, so your smaller implementation is fine.
Fyi though - if the client is going to use these classes for databinding then they need to be properties in the class. Fields won't be bound.
In addition to all of the other answers, properties allow for validation to be ran when the property is read from or written to. That would take more work to do when using fields.
Related
I am a bit confused so to why we set the set as private in the following. My confusion is not specifically to do with the private property, but in the context of domain objects and getting them from the user input ([FromForm])
public class ObjectA
{
public string Name { get; private set; }
public string Title { get; private set; }
public ObjectA(string name, string title)
{
Name = name;
Title = title;
}
}
But in reality when ObjectA is passed into a controller with [FromBody], all those properties get sent into the constructor automatically defeating the purpose of private set.
I guess I am not fully understanding this whole concept of private sets in domain objects
It's common rule when design DDD objects. makes object to be immutable. Property's value should be changed only inside your domain via constructor or public method. That helps you more focus to your domain and avoid side effects.
Kind of these objects are not the Data Transfer Object(DTO) that you mentioned: [FromBody]
interface IAnimal
{
string Name { get; set; }
}
class Dog : IAnimal
{
private string name;
public Dog(string name)
{
Name = name;
}
public string Name
{
get { return name; }
set { name = value; }
}
}
In general, it's better to go through the property getter and setter whenever possible unless there is a specific reason not to. If the property setter has a side effect (like firing a notification) that you don't want in a specific situation, it's ok to assign to the backing field directly from within the object, but try to avoid getting into that sort of situation.
The reason it's good to use the property getter and setter, even in the implementing class itself: when/if you need to change the implementation of the getter/setter in the future, such as adding needed side effects, your code will already be in a good position to honor the new getter/setter semantics.
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.
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");
}
I know this must be a common question, but take a look:
Here i have a test class:
public class EmployeeClass
{
private int _id;
private string _name;
private double _salary;
public int id
{
get{...}
set{...}
}
public string name
{
get{...}
set{...}
}
//and so on
}
The question is: for me, it doesnt make sense to have public properties matching ALL private fields.
What is the approach to limit the access to itens of the class?
At the time of initialization do i access the fields directly, as in:
public EmployeeClass(int id, string name, double salary)
{
_id = id;
_name = name;
_salary = salary;
}
AND MAKE ALL (at least the ones that must have some sort of immutability) readonly?
What's the best approach here?
Thank you for your opinions
There are many attitudes, two of them that helps avoiding getters on the class are:
East oriented code
Getters and Setters are evil
In general (and this is only a tiny taste), it is not recommended to have many public setters on the class.
To answer the question from a language convention point of view, prior to C# 3.0, access to internal data was typically performed by declaring private fields with public properties providing read and/or write accessors:
public class Employee
{
private int _id;
public int Id
{
get { return _id; }
set { _id = this; }
}
}
Note: In .Net, properties are in PascalCase by convention.
While the purpose of properties are to provide encapsulation around accessing an object's internal state, properties are often used merely as a pass through to private field access as a placeholder in the event additional behavior is needed in the access or computation of the state. Because this pattern leads to a lot of verbose and repetitive coding, Microsoft introduced the Auto-Implemented Properties feature in C# 3.0. Auto properties allow the developer to declare properties which are automatically backed by a private variable:
public class Employee
{
public int Id { get; set; }
}
Eric Lippert has a great series on the different kinds of immutability in c#. He's also got some examples for how to implement the different kinds of immutability.
What he calls "write-once immutability" is the kind where initialization is done in the constructor of the class and all fields are marked as private readonly fields.