My POCO's structure basically goes like this:
Person which has: Addresses, Phones, CaseNotes, NoticeOfActions.
I started writting a PersonExtension class which I found quite useful with, say, the following example method:
public static Person GetPersonsPhones(this Person person, string userID)
{
using (var context = ConnectDataContext.Create())
{
var pPhones =
context.tblPhones.Where(phones => phones.PersonID == person.PersonID).Select(
phones =>
new Phone()
{
PhoneID = phones.PhoneID,
PhoneType =
new PhoneType
{
PhoneTypeID = phones.tblAdminPhoneType.PhoneTypeID,
TypeDescription = phones.tblAdminPhoneType.PhoneTypeDesc
},
PhoneNumber = phones.PhoneNumber,
Extension = phones.Extension
});
person.Phones = pPhones.ToList<Phone>();
return person;
}
}
Now I have similar Extension Methods for Person that get the Address Collection. What I am wondering is if there is a point where this is detrimental. Due to the nature of my environment almost everything fits under Person in the has-a way.
Is that okay or is there something bad that I will run into from that? Am I incurring WAY more overhead that way?
The alternative seems to be to simply pass the Person.ID since that is what I need to get the Phones from the DB and then add it to my Person object but that seems, to me anyway, to be the same thing.
I think there is a communication breakdown here which is most likely my fault as I don't always use the right words for things.
In my DB there is tblPerson and tblPhone. I have a class called Person and a class called Phone. My Person class has a Property of IList<Phone>Phones.
The Extension Methods in question are for CRUD methods for the child properties of my Base Class.
i.e. Person.GetPhones() fills the IList<Phone>Phones Property of that Person object. Person.SavePhones() would Save any changes to the Phones to the DB for that Person object.
I am not arguing that what I am doing is RIGHT(I doubt it is...:() just trying to make sure everyone understands what I am asking.
Also, I am using LinqToSQL for the DB access.
Your person here should be a fully fledged domain object, not a POCO. The person should tell some thing their phone numbers, the person should not be responsible for going off to the database and fetching them out! The later applies whether you choose an extension method or not.
Regarding your question however, I see extension methods as way of extending some functionality of third party code. For example, you can do ToUpper() on strings. It would be nice to extend this to do Title Case. Here we are extending the behavior. We are "adding" to third party code without having the source at hand, because the alternative would be to introduce a new object that wrapped string to do so. Extension methods here then are only really syntactic sugar.
If you own the code, then extension methods are pointless because you can just make the method a fully fledge method on the class in question. The reason I say this is that with a proper method you can access private fields of the class you are extending, therefore using an extenstion method you are limited to public visibility, just like a normal static method.
I think the main downside would tend to be code organization. Isn't the point of OOP to try and keep related code together?
I'm curious why you are using an extension method here. If Person is an entity object, I would create a partial class that extends the entity class. Seems to be a bit better organization here to me.
If you are using POCO classes with EntityFramework code-first model, you should be able to write your POCO class like this (including only the Phones for now, just to demonstrate):
class Person
{
public long Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Phone> Phones { get; set; }
}
class Phone
{
public long Id { get; set; }
public string Name { get; set; }
public long PersonId { get; set; }
public virtual Person Person { get; set; }
}
Now you can access myPerson.Phones directly and there is no need for your extension method.
If it's your class then you should write real methods for the class. Extension methods are useful for adding functionality to classes that you can't change, for example, a class from a library you don't have the source for and that you can't just derive from.
Related
Let's say I have a class with public properties. Example of a class.
public class Book
{
public string Title { get; set; }
public string Author { get; set; }
}
To optimize queries, only modified fields must be sent to the database.
How can I track changes to the properties of the book class, provided that I can't rewrite the code of the class itself in any way?
The book itself is in the cache for updating, it can be accessed from outside the link.
I've been working on it for a week.
I searched through the reference books on reflection, but I didn't find anything. Although you can somehow use reflection to read the set method of the book class, add your own code, and put everything back in the method.
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.
I personally don't have my entities implement interfaces. For a Task class I wouldn't have ITask that just had the same properties defined on it.
I've seen it done a few times though, so I'm wondering where that advice comes from, and what benefits you get from it.
If you're using an ORM then the argument that says "I can change my data access" is irrelevent, so what other reason is there for doing this?
UPDATE:
A good point was made in the comments about INotifyPropertyChanged. That wasn't my point though - I'm talking about having something like this:
public interface ITask
{
int Id { get; set; }
string Description { get; set; }
}
public class Task : ITask
{
public int Id { get; set; }
public string Description { get; set; }
}
I went down this road once (interfaces for value objects). It was a royal pain in the backside, I recommended against it. The common arguments for it are:
Mocking:
They are value objects. Nought to mock. Plus mocking ends up being a large pain than either writing a builder (in Java) or using the named arguments stuff in C#.
Readonly views:
I must admit I still prefer to make something immutable by default, only making it mutable if absolutely required.
Hidden functionality:
Generally scope has covered this one for me.
The major benefit of this is that it is a way of exposing your entity as a "read-only" version (as long as your interface does not expose setters of course).
We're doing quite a bit of unit testing and so often want to mock out things we're not testing. Although I don't like it, we've ended up using interfaces all over the place because it makes it a lot easier to mock things.
In theory most of the mocking frameworks can mock normal classes too, but in practice this has caused us issues because we sometimes do clever things with reflection and the type of the mocked class isn't the same as the original. So doing:
var myTask = MyIoCProvider.Get<Task>();
var taskType = typeof(myTask);
Was unpredictable. Whereas:
var myTask = MyIoCProvider.Get<ITask>();
var taskType = typeof(myTask);
Gives you as taskType that IS definitely derived from ITask.
So interfaces just give us a way of making our system more mockable.
If you were thinking in terms of using DomainEvents than data structures such as the task really do need to implement an interface
public interface IDomainEvent
{
Guid EventId { get; }
Guid TriggeredByEvent { get; }
DateTime Created { get; }
}
public class OrderCancelledEvent : IDomainEvent
{
Guid EventId { get; set; }
Guid TriggeredByEvent { get; set; }
DateTime Created { get; set; }
// And now for the specific bit
int OrderId { get; set; }
}
Or similarly if you have a common data access layer that may need to take in a standard base class of IEntity but I wouldn't have an interface for each type if it is just a data structure as you describe in your post.
When you are handling Domain Objects that actually expose behaviour you may then want to have an interface for unit testing.
I think some programmers just use interfaces, because they heard interfaces are good so they ended using them everywhere without thinking about actual pros and cons.
Me personally, I never use interfaces for entities that only represent a piece of data like db row for example.
I have multiple Linq2Sql Classes such as "Article" "NewsItem" "Product".
They all have a title, they all have a unique ID and they all have a Summary.
So, I created an interface called IContent
public interface IContent {
int Id { get; set; }
String Title { get; set; }
String Summary { get; set; }
String HyperLink { get; set; }
}
In my code, I'm trying to make it possible to pass a List<T> that implements IContent and then use those common properties that I have implemented in each of the partial classes in my project.
So, just to clarify
Article is a Linq Entity.
I create a partial class and implement IContent Here's a snippet of Article.cs:
#region IContent Members
public int Id {
get {
return this.ArticleID;
}
set {
this.ArticleID = value;
}
}
Pretty Simple. In my code I'm trying to this, but I don't know where I'm going wrong:
List<IContent> items;
MyDataContext cms = new MyDataContext();
items = cms.GetArticles();
// ERROR: Can not implicitly convert List<Article> to List<IContent>
If my Article class implement IContent why can't I pass in Articles? I don't know what the objects that are going to be passed in.
I know I can do this with Inheriting a base class, but using LinqToSQL doesn't use regular objects.
I'm sure it's something simple that I'm missing.
This is because the List class and interface aren't covariant. If you're using .NET 4.0 and C# 4.0, you can actually use covariance on the IEnumerable<> interface, which should be okay for LINQ applications.
There's a good FAQ covering those topics.
Have you tried
items = cms.GetArticles().Cast<IContent>().ToList();
This is classic case that calls for co-variance in C# 4.0. You only have to change List<Article> to IEnumerable<Article> to make this assignemnt work:
IEnumerable<IContent> articles = myContext.GetArticles();
If you are stuck with .NET 3.5 you can just use Linq Cast<T>():
IEnumerable<IContent> articles = myContext.GetArticles().Cast<IContent>();
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.