A simple example.
alt text http://img19.imageshack.us/img19/1854/51445300.jpg
A have a class TDMReader which is a buldier of TDMFile objects and I am using Auto Implemented Properties f.e.
public string Name
{
get;
set;
}
public Group[] Groups
{
get;
set;
}
What I want to do is to make setter accessible only for TDMReader methods.
In C++ i could have friends methods to access private variables, in Java I could make them in one packet and so access to fields. I have some ideas but with this auto-implemetation is a bit more complicated to do.
Any ideas with a nite solution?:)
Automatic properties have no bearing on this - the same options are available for automatic properties and "manual" properties. You can restrict the access of the setter like this:
// Setter access only to this type and nested types
public string Name { get; private set; }
// Setter access within the assembly
public Group[] Groups { get; internal set; }
etc
... but you can't do it for a single class (unless that class is nested within the declaring type, in which case private would be fine). There's no namespace-restricted access in .NET or C#.
(It's not entirely clear which class the properties are declared in - if they're TdmReader properties, then just make them private. If they're TdmFile properties, you have the problem described above.)
Like this:
public string Name
{
get;
private set;
}
public Group[] Groups
{
get;
private set;
}
By adding the private keyword, the setters will only be accessible by code in the same class. You can also add internal to make it accessible to code in the same project.
Note that exposing an array as a property is extremely poor design.
Instead, you should expose a Collection<Group> or ReadOnlyCollection<Group>, in the System.Collections.ObjectModel namespace.
Related
So, I'm currently working on a strategy game that involves 3 types of buildings: "Production", "Storage", and "Refining".
Any building can belong to one or more of these types, so a Storage building could also be a Refining building and should then inherit the functionality of both of these types.
Example:
public class Stronghold : Building, IStorage, IRefining, IProduction
{
public RefiningOption[] RefiningOptions { get; set; }
}
public interface IRefining
{
public RefiningOption[] RefiningOptions { get; set; }
}
I went about implementing this using interfaces, but I am running into the issue that Unity does not allow you to serialize properties and interfaces can not contain fields.
Is there a way around this that would allow me to inherit from multiple different types in a neat way, or am I approaching this all wrong? I can think of a solution that would involve using separate components for the functionality of each building type, but before I implement that, I wanted to know what the "correct" solution would be.
Thanks in advance. I'm trying to expand my toolset, so any feedback is welcome.
Just like the answer above but in a more "compact" way
[field: SerializeField] public RefiningOption[] RefiningOptions { get; set; }
This is an auto-property that generates a backing field that you can access directly by typing [field: "Your_Attribute_Here"], this is the same as having a [Serialized] private field with a public property exposing it.
just like this ? create a field in private. and this private field can be serialize
private RefiningOption[] _refiningOptions;
public RefiningOption[] RefiningOptions
{
get { return _refiningOptions; }
set { _refiningOptions = value; }
}
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.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C#: Public Fields versus Automatic Properties
I read properties in C# are declared or used to provide access of private members to others. In that case, when we are declaring public members, do we still have to declare properties for them.
In the following example, they have declared properties for public members. I don't know why ?
class Customer
{
public double TotalPurchases { get; set; }
public string Name { get; set; }
public int CustomerID { get; set; }
}
thanks!
This article gives you a good overview to properties and its overuse
http://www.codinghorror.com/blog/2006/08/properties-vs-public-variables.html
Using properties instead of public fields allows non-breaking changes in how these properties are implemented in the next release - with public fields any change is breaking.
For example you could change the implementation of TotalPurchases to perform a calculation instead of returning the value of a backing field directly. From the point of view of the consumer of the class this change is non-breaking and does not affect how your application works.
public double TotalPurchases
{
get
{
return CalculatePurchases();
}
}
So first of all, properties in C# are declared for many reasons, and it's not about being private at all.
You can, for example, make the getter public and the setter private:
public double TotalPurchases
{
get;
private set;
}
Also, for some frameworks backed up by reflection, they look for properties and not fields.
In this case, properties are a must, even if it looks useless when nothing is done in the getter/setter.
I have a base class (PrintProviderBase). It holds some states (PrinterUnavailable, NoPaper, ...).
Then I inherit from this class : ColorPrintProvider, BlackAndWhitePrintProvider ...
I was assumed that if the base class has a property like this:
private PrintStateEnum State { get; set; }
Then each child class (different print providers) have it's own state (though nothing is static). It seems one instance of the base class is shared among them while I meant to have a copy of the base class in each child class so the common functionality and state can be encapsulate into base class.
Now if a print provider goes into NoPaper state, other ones stop printing due to incorrect state. How can I change this behavior ?
Each instance of ColorPrintProvider and BlackAndWhitePrintProvider will have their own (and distinct) instance of the State value, although none of them will be able to access it unless you make it public or protected (or provide other properties or methods which expose it). In general the value would only be shared across instances if it were static.
In the code you posted, State is a private to PrintProviderBase and would not be visible to the derived types like ColorPrintProvider and so on.
Make State a public property and use Composition not inheritance. Keep a member of PrintProvider (change the name from PrintProviderBase) in ColorPrintProvider, BlackAndWhitePrintProvider and so on.
Sample code:
public class PrinterState
{
public Boolean IsPaperTrayEmpty { get; set; }
public Int32 CartridgeLevel { get; set; }
}
public class ColorPrintProvider
{
public PrinterState CurrentState { get; private set; }
private void UpdateCurrentState()
{
// update the current state
// based on / after some events like RequestForPrint, PrintCompleted...
}
}
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.