What are some cool applications for custom attributes in CLR/C# code that you've done or heard about? Also interesting new uses of the standard attributes is also ok!
Edit: Since Java's annotations seems to be the same as CLR's attrbutes, uses of Java annotations is also valid.
postsharp, which uses attributes to inject code (AOP)?
[TypeDescriptionProvider] which can be used to provide a custom runtime property model - either completely different properties, or perhaps faster ones
And some core ones that are often overlooked:
[TypeForwardedTo] - used to move types between assemblies without re-building
[PrincipalPermission] - used to automatically enforce security on members
While not strictly C#, I've found an interesting use of Java annotations (= C# attributes) for marking student's assignments. Every semester I program a marking robot for students, and it turns out that first-year students for some reason don't seem to be able to follow instructions precisely, which of course causes the marking robot to fail. So what I do is go through their code, find all the methods that didn't meet the specification and fix them. Then I put an annotation (=attribute) onto each of the methods that were wrong, telling the marking robot to mark them down. It's probably the most simple and direct way to do this I think.
Check out xUnit and see how attributes are used to mark unit tests for expected behavior as well as feed data into tests. Attributes are used in a more meaningful manner than MSTest or NUnit.
From Samples\TestMethodExtensibility\Example.cs:
public class Example
{
static int val;
[RepeatTest(5, Timeout=250)]
public void RepeatingTestMethod()
{
Thread.Sleep(100);
Assert.Equal(2, 2);
if (val == 0)
{
val++;
Thread.Sleep(1000);
}
}
}
From test.xunit.extensions\DataTheories\TheoryAttributeTests.cs:
internal class TestMethodCommandClass
{
public static IEnumerable<object[]> EmptyData
{
get { return new object[0][]; }
}
public static IEnumerable<object[]> NullData
{
get { return null; }
}
public static IEnumerable<object[]> TheoryDataProperty
{
get { yield return new object[] { 2 }; }
}
[Theory, PropertyData("EmptyData")]
public void EmptyDataTheory() { }
[Theory, PropertyData("NullData")]
public void NullDataTheory() { }
[Theory, OleDbData(
#"Provider=Microsoft.Jet.OleDb.4.0; Data Source=DataTheories\UnitTestData.xls; Extended Properties=Excel 8.0",
"SELECT x, y, z FROM Data")]
public void TestViaOleDb(double x,
string y,
string z) { }
[Theory, PropertyData("TheoryDataProperty")]
public void TestViaProperty(int x) { }
[Theory, ExcelData(#"DataTheories\UnitTestData.xls", "SELECT x, y, z FROM Data")]
public void TestViaXls(double x,
string y,
string z) { }
}
For details see:
http://www.codeplex.com/xunit
nunit of course
the usages of attributes has been prided by kent beck:
NUnit 2.0 is an excellent example of idiomatic design. Most folks who port xUnit just transliterate the Smalltalk or Java version. That's what we did with NUnit at first, too. This new version is NUnit as it would have been done had it been done in C# to begin with.
source: http://www.nunit.org/
I have a case, where I want to present the actual implementation of an interface as data as well. This can be done via Reflection of course, but by using a specific attribute on the members I want to expose as data, I can encapsulate the work needed to do this.
The end result is that I create my implementation, decorate the desired members and then I can query the members through both code and data without having to do the Reflection code in each case.
Sometimes, I use attributes to decorate classes or methods and use reflection to get the 'attributed' data.
Maybe a bit difficult to explain, but the last thing for which I've used attributes, is in a system where I have a couple of entities in a database.
Each entity has some kind of 'code', and each entity can also have some interpretation rules.
In my project, I have one entity class, which represents an entity that exists in the Database, and, I also have a set of 'Rule' classes.
One Rule class contains the interpretation logic of a given entity.
In order to 'link' a certain 'Rule' (interpretation) to a specific instance of my entity, I've created a custom Attribute.
I decorate my 'Rule' class with this attribute, and through the attribute, I define for which entity this is a Rule.
Then, when I load an entity from the DB, I inject the correct rule into that entity.
A little bit of code to make things clear:
public class MyEntity
{
public string Code
{
get;
private set;
}
public bool IsValidFor( ... )
{
IRule rule = RuleRegistry.GetRuleFor(this);
if( rule.IsValid() ) ...
}
}
[RuleAttrib("100")]
public class MyRule : IRule
{
public bool IsValid()
{
}
}
This is just a little example, but I think you'll catch the drift.
The RuleAttrib attribute on the MyRule class, says that this is a Rule that should be applied to the instance of MyClass which has a code "100".
The RuleRegistry instance is able to retrieve the correct IRule for the current Entity (using reflection).
Another example in where I've used attributes, in combination with Postsharp, is the implementation of a 'locking' system:
http://fgheysels.blogspot.com/2008/08/locking-system-with-aspect-oriented.html
we use custom java annotations to mark special purposes of certain methods, mostly targeted at developers:
#ScriptingAPI -- marks code that is exposed as part of our scripting API (warns developers that changes could affect the public API)
#Transaction -- marks methods on the database facade that are starting/commiting a transaction (we have a dedicated transaction handler class that respects this annotation)
#NeedsAttentionToSupportFoo -- if we know that feature Foo is a requirement that we will need to address in the near future, we use an annotation to mark code that we will need to touch to support it, i.e. when we come across a piece of code that makes us think "ah, this will need to be changed to support Foo", we annotate it. if the implementation of Foo is postponed or will never happen, it's easier to remove the annotation than to revert pre-mature optimizations scattered all around in the code.
another good example usage of a custom annotation is covered in this java specialist newsletter: enforcing a public no-args constructor in all sub classes.
Castle's ActiveRecord uses attributes. It hides some of the set-up complexity of NHibernate by decorating your Model objects with attributes indicating classes and fields that should be persisted to the database (and how). There is also use of attributes within the validation component to add model-based validation into ActiveRecord and the Monorail stack.
Related
Basically, I have the following scenario:
public abstract class FooBase<T> where T : FooBase<T>
{
public bool IsSpecial { get; private set; }
public static T GetSpecialInstance()
{
return new T() { IsSpecial = true };
}
}
public sealed class ConcreteFooA : FooBase<ConcreteFooA> { ... }
public sealed class ConcreteFooB : FooBase<ConcreteFooB> { ... }
But, the problem I see here is that I could have done ConcreteFooB : FooBase<ConcreteFooA> { ... }, which would completely mess up the class at runtime (it wouldn't meet the logic I'm trying to achieve), but still compile correctly.
Is there some way I haven't thought of to enforce the generic, T, to be whatever the derived class is?
Update: I do end up using the generic parameter, T, in the FooBase<T> class, I just didn't list every method that has it as an out and in parameter, but I do have a use for T.
To answer your question:
No, there is no compile time solution to enforce this.
There are a couple of ways to enforce this rule:
Unit Testing - You could write up a unit test (or unit tests) to ensure that the compiled types are passing themselves in as the generic parameter.
Code Analysis - You could create a custom code analysis rule that enforces this, and then set that rule as an error (vs warning). This would be checked at compile-time.
FxCop Rule - Similar to the Code Analysis rule, except if you don't have a version of Visual Studio that has built-in support for Code Analysis, then you can use FxCop instead.
Of course, none of these rules are enforced on a standard compilation, but instead require additional tools (Unit Testing, Code Analysis, FxCop). If someone took your code and compiled it without using these tools you'd run into the same issue... of course, at that point why is someone else compiling your code without running your unit tests or Code Analysis/FxCop rules?
Alternatively, and I don't recommend this, you could throw a run-time error. Why not? According to Microsoft:
If a static constructor throws an exception, the runtime will not
invoke it a second time, and the type will remain uninitialized for
the lifetime of the application domain in which your program is
running.
That really doesn't solve your issue. On top of that, throwing an exception during static initialization is a violation of Code Analysis CA1065:DoNotRaiseExceptionsInUnexpectedLocations. So, you're going in the wrong direction if you do this.
There is no compile-time way to enforce this, as far as I know. It can, however, be enforced using a run-time check. No unusual user actions would typically be able to cause this, (just incorrect coding) so it's similar to having Debug.Assert in places (and, in fact, you could implement it using that, if you like). E.g.
public abstract class FooBase<T> where T : FooBase<T>
{
protected FooBase()
{
Debug.Assert(this.GetType() == typeof(T));
}
}
I don't know why you have this as a requirement. I would first suggest that you go back and look at 'your object model and determine why you feel you need this requirement and determine if there's a better way to accomplish whatever it is you're trying to achieve.
I think I see one problem with what you have above: no generic parameters in your definitions/declarations of classes ConcreteFooA and ConcreteFooB.
It looks as though it may be better for you to create an interface IFooBase and have your concrete implementations implement the interface. In every instance where you want to work with an IFooBase, you'd use a variable of type IFooBase.
So:
public interface IFooBase { /* Interface contract... */ }
public class ConcreteFooA : IFooBase { /* Implement interface contract */ }
public class ConcreteFooB : IFooBase { /* Implement interface contract */ }
// Some class that acts on IFooBases
public class ActionClass
{
public ActionClass(IFooBase fooBase) { this._fooBase = foobase };
public DoSomething() { /* Do something useful with the FooBase */ }
// Or, you could use method injection on static methods...
public static void DoSomething(IFooBase fooBase) { /* Do some stuff... */ }
}
Just some ideas. But I don't think you can accomplish what you want to do with Generics alone.
It's not possible and it should not be, because according to L in SOLID:
Liskov substitution principle: “objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program”.
So actually the compiler is doing what it was meant to do.
Maybe you need to change the design and implementation of your classes for example by employing a Behavioral Pattern. For instance if an object should present different algorithms for a specific calculation you could use Strategy Pattern.
But I can not advise on that since I am not aware what exactly you want to achieve.
I need to implement a little bit of C++ style 'friend' functionality in C# and am looking for ideas.
Consider two classes that are very closely related: Node and NodePart. Nodes contain NodeParts which are added via public AddPart() calls from other systems with parts that those systems construct. Node needs to "reach into" NodePart to do some very specific notifications that NodePart will distribute via separate virtual protected methods to any derived classes after some processing. (For anyone familiar with component-based game object programming, this is the same kind of thing.)
I'd like to be able to have NodePart give Node a way to get at these few notification methods without letting any other types in the system do it. It's not necessary for Node to access any other NodePart internals, just forward along some private notifications.
Now, putting these classes in an assembly and using 'internal' would obviously do the trick, but I'm looking for a better pattern than that. (I'm not really interested in spawning new assemblies for every set of classes I'd like to do this with in the future.)
Aside from reflection + invoke, which is yucky and brittle, what other patterns can you think of to solve this problem here? My spidey senses tell me that interfaces are part of the solution, but I can't think of how.
(Note: I'm ok with security through obscurity. This system doesn't have to be 100% proof against misuse - just enough to discourage people from doing what they should not. We're not building defibrillators here.)
Update: lots of the below answers require multiple assemblies. As I mention above, I'd really like avoid this. I do not want to put one system per assembly. We have enough of the things as is, and I can't go down the IL linking route due to our use of XAML. But thanks for the answers anyway. :)
Update 2: I messed around in Linqpad and came up with a few options based on the answers below. Which do you like worst/least and why?
Option 1: Obsolete
#pragma warning disable 612 // doc this
public sealed class Node : NodePart.SystemAccess {
#pragma warning restore 612
NodePart _part;
public NodePart Part {
get { return _part; }
set { _part = value; NotifyAdded(_part); }
}
}
public class NodePart {
void NotifyAdded() { Console.WriteLine("Part added"); }
[Obsolete] public class SystemAccess // doc this
{
protected void NotifyAdded(NodePart part) { part.NotifyAdded(); }
}
}
Not bad. A little weird but the weirdness is very confined. I'm leaning towards this one because it's so much more compact than the next option.
Option 2: Access + Hack
public sealed class Node {
static readonly NodePart.ISystemAccess _systemAccess;
static Node() {
_systemAccess = (NodePart.ISystemAccess)typeof(NodePart)
.GetNestedTypes(BindingFlags.NonPublic)
.Single(t => t.Name == "SystemAccess")
.GetConstructor(Type.EmptyTypes)
.Invoke(null);
}
NodePart _part;
public NodePart Part {
get { return _part; }
set { _part = value; _systemAccess.NotifyAdded(_part); }
}
}
public class NodePart {
void NotifyAdded() { Console.WriteLine("Part added"); }
internal interface ISystemAccess {
void NotifyAdded(NodePart part);
}
class SystemAccess : ISystemAccess {
void ISystemAccess.NotifyAdded(NodePart part) {
part.NotifyAdded();
}
}
}
Hacka hacka hacka. My original version didn't have the reflect+invoke and would have relied on SystemAccess being non-obvious. That might be ok too but I kind of like the bit of extra security I get here, even though it's probably not necessary.
Make NodePart a nested class in Node, it will be able to access all of its private members.
If that's not possible (don't want a using Node?), then you could try partial classes. I don't know how that would work though, because I've never really used them in a more advanced way like that.
Are friend assemblies what you're looking to do? They've been in the framework since 2.0, but I don't think it's been very well advertised.
Friend assemblies allow you to access internal methods in assembly B from assembly A, but protected and private members are still hidden.
Not sure if this will help, but thought it may.
Oh, and the one drawback is that you have to strong name those assemblies.
The only way I can think of using interfaces is to implement the fields of NodePart explicitly, which would require any derived classes to be downcast to the interface if they wish to access them.
interface INodePart {
T SomeValue { get; }
}
class NodePart : INodePart {
T INodePart.SomeValue { get; private set; }
}
class Node {
void AddNodePart(NodePart np) {
T val = (np as INodePart).SomeValue; //require downcast here.
...
}
}
Note that you need to downcast even inside NodePart if you wish to access Somevalue.
This obviously isn't fool proof - anyone can downcast if they want, but it's certainly a discouragement.
To add to the discouragement, you could mark the interface with the [Obsolete] attribute, and wrap the NodePart and Node classes inside a disabled warning block which will mean anyone else attempting to use the INodePart will be given a warning, but your code will not.
#pragma warning disable 612
class NodePart : INodePart { ... }
#pragma warning restore 612
You could get strict on this, and add /warnaserror:612 to your build arguments, but it'll break your code if you rely on any other code marked Obsolete elsewhere. (Although you can enable/disable this for certain files, but will probably require manually hacking the .csproj file)
InternalsVisibleto is the closest you will get to "Friend" in C#
http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx
I believe you can actually make an Interface internal, so the behaviour you need could be encapsulated in the main assembly of your project, but anything else wouldn't see the behaviour ?
You might, if you really wanted to, be able do this using attributes such that the friend classes store a cryptographic hash of whatever the "Friended" class can access of the friend class's code at run time using reflection, and have a public version of the method that checks this hash each time it's called. I haven't tried this, and am not sure reflection gives you anything suitable to hash against, like the binary bits of the friend class.
Or you might be able to use the .NET security in a similar way.
Just brainstorming, these wouldn't be worth it if you can avoid it.
Say I have a group of classes which generate documents from templates. For example...
class CustomerInvoice
{
public satic string TemplatePath
{
get { return #"C:\Templates\InvoiceTemplate.doc"; }
}
public static DocumentType DocumentType
{
get { return DocumentType.WordDocument; }
}
public static void Create(Customer customer, int orderNumber)
{
//...
}
}
All of these classes share the same method names, but not necessarily method signatures.
For example, I might have
CustomerInvoice.Create(Customer customer, int orderNumber);
DespatchNote.Create(Customer customer, int orderNumber, Warehouse warehouse);
PackingLabel.Create(int orderNumber);
... or whatever (struggling to come up with sensible examples).
Is there a mechanism in OO which specifies what method names a group of classes has in this way? I'm really thinking of just having a way to enforce consistent implementation and naming accross a group of similar objects, so they are more intuitive for consumers. Would a case like this be considered a valid/worthwhile use of any such technique?
No, there is no construct for that. Static methods in particular have no way of enforcing any commonality. If is was an interface you could have something like Create(object) or Create(T) (for some T defined on a generic interface) and take a single parameter to represent te state.
consistent implementation and naming accross a group of similar objects, so they are more intuitive for consumers
Since you're talking about ensuring the public interface of your API conforms to a certain system, I don't think there are necessarily going to be any OOP constructs that will help.
What might help however is any one of a number of tools intended to control style and design. I'm thinking of things like StyleCop, FxCop, and NDepend, all of which allow the creation of custom rules (with varying amounts of pain!). In particular, NDepend would allow you to set up a Code Query Language rule along the lines of
WARN IF Count == 0 IN SELECT METHODS WHERE NameIs "Create" AND IsStatic
which (applied to a suitable namespace) would warn if any particular class did not have a static method (of any signature) named Create
what I mean by that is:
I basically have a class that has too many properties and functions now. To remain performant and understandable, it needs to shrink somehow. But I still need all those properties and methods somewhere.
It's like this right now:
class Apple
float seedCount;
...
...about 25 variables and properties here.
void Update() <-- a huge method that checks for each property and updates if so
In most cases the class needs almost none of those properties. In some cases in needs to be able to grow very selectively and gain a feature or lose a feature.
The only solution I have come up with, is that I create a bunch of classes and place some properties in there. I only initialize this classes object when one of those properties is needed, otherwise it remains null.
class Apple
Seed seed;
Many problems because of that:
I constantly have to check for every single object and feature each frame. If the seed is not initialized I don't have to calculate anything for it. If it is, I have to.
If I decided to put more than 1 property/feature into the Seed class, I need to check every single one of those aswell.
It just gets more and more complicated. The problem I have is therefore, that I need granular control over all the features and can't split them intelligently into larger subclasses. Any form of subclass would just contain a bunch of properties that need to be checked and updated if wanted.
I can't exactly create subclasses of Apple, because of the need for such high granular control. It would be madness to create as many classes as there are combinations of properties.
My main goal: I want short code.
It would be madness to create as many classes as there are combinations of properties.
Sounds like you might be looking for the Decorator Pattern. It's purpose is to make it easier to manage objects that can have many different combinations of properties without an exponentially growing heirarchy. You just have one small subclass for each property or behavior (not necessarily one C# property, just something you can group together) and then you can compose them together at runtime.
In your case, each Apple decorator class will override your Update method, and make the calculations necessary for its parts, and then call base.Update to pass it to the next in line.
Your final answer will heavily depend on exactly what your "Apple" really is.
After reviewing your comments and samples in my other answer, I've thought about the Decorator pattern and how it was being used vs how you want things to work. I've come to the conclusion that Decorator is not right for this purpose. I'm thinking Strategy instead. I have modified the previous sample code for you to take a look at.
I've gotten rid of the decorators altogether. The Broodfather abstract class remains. It has two additional properties an IBroodfatherMagicAbility and an IBroodfatherBloodthirstAbility. This two properties will allow you to access the different attributes that pertain to those abilities, however the key to this all is that the strategy for implementing the abilities can change at runtime (see Strategy pattern).
There are two classes each that implement a "strategy" for both bloodthrist and magic.
IBroodfatherBloodthirstAbility.cs - this is the interface that all "bloodthirst strategies" must implement.
BroodfatherNonBloodThristy.cs - class that implements the attributes for non-bloodthirsty.
BroodfatherBloodThristy.cs - class that implements the attributes for bloodthirsty.
IBroodfatherMagicAbility.cs - this is the interface that all "magical strategies" must implement.
BroodfatherNonMagical.cs - class that implements a strategy for non-magical.
BroodfatherMagical.cs - class that implements a strategy for magical.
BasicBroodfather.cs - this is similar to the previous example, except that now when an instance is created the magic and bloodthrist properties get set to new instances of the non-magical and non-bloodthristy strategy objects.
Program.cs is the driver that shows the classes and how the different strategies can get swapped in and out at runtime.
I think you'll find that more suited to how you wanted things to work.
you may use a nested class in Apple class
http://msdn.microsoft.com/en-us/library/ms173120(VS.80).aspx
I think the key thing here is that you are trying to hold everything in one class. Because of that, the class must be constantly checking what it has and what it doesn't. The solution is to create subclasses or decorators that already know whether or not they have a particular thing. Then they don't have to be checking it each time.
Because you have so many properties which may be combined in different ways, it sounds like the decorator solution is more up your alley.
I think you're in the right path: composition. You compose your class with the other classes that are needed. But you also need to delegate responsibility accordingly. In your example, it's the Seed class that should be responsible for checking it's internal state, and Apple just delegates to it.
As for the optional features problem, maybe you can use null objects instead of null references. This way, you don't need to check for null everytime, and the code is more consistent.
I've been pondering this question for a bit and I've come up with an alternate solution. This may be a bit unorthodox and anti-object oriented, but if you're not faint of heart read on...
Building upon the Apple example: the Apple class can contain many properties, these properties which could be categorized into related groups. For the example I rolled with an Apple class with some properties related to the apple's seeds and others related to the apple's skin.
Apple
a. Seed
a1. GetSeedCount
a2. ...
b. Skin
b1. GetSkinColor
b2. ...
I'm using a dictionary object to store all the apples properties.
I wrote extension methods to define accessors to the properties, using different classes to keep them separate and organized.
By using a dictionary for the properties, you can iterate through all properties stored thusfar at any point (if you have to check all of them, as it sounded like you needed in your update method). Unfortunately you lose strong typing of the data (at least in my sample I did because I'm using a Dictionary< string, string>. You could have separate dictionaries for every type needed, but that would require more plumbing code to route the property access to the correct dictionary.
Using extension methods to define accessors to the properties allows you to separate the code for each logical categories of properties. This keeps things organized into separate chunks of related logic.
Here is a sample I came up with to test how this would work, given with the standard warning that if you were to continue down this path robustification would be in order (validation, error handling, etc.).
Apple.cs
namespace ConsoleApplication1
{
using System.Collections.Generic;
using System.Text;
public class Apple
{
// Define the set of valid properties for all apple objects.
private static HashSet<string> AllowedProperties = new HashSet<string>(
new string [] {
"Color",
"SeedCount"
});
// The main store for all properties
private Dictionary<string, string> Properties = new Dictionary<string, string>();
// Indexer for accessing properties
// Access via the indexer should be restricted to the extension methods!
// Unfortunately can't enforce this by making it private because then extension methods wouldn't be able to use it as they are now.
public string this[string prop]
{
get
{
if (!AllowedProperties.Contains(prop))
{
// throw exception
}
if (Properties.ContainsKey(prop))
{
return this.Properties[prop];
}
else
{
// TODO throw 'property unitialized' exeception || lookup & return default value for this property || etc.
// this return is here just to make the sample runable
return "0";
}
}
set
{
if (!AllowedProperties.Contains(prop))
{
// TODO throw 'invalid property' exception
// these assignments are here just to make the sample runable
prop = "INVALID";
value = "0";
}
this.Properties[prop] = value.ToString();
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
foreach (var kv in this.Properties)
{
sb.AppendFormat("{0}={1}\n", kv.Key, kv.Value);
}
return sb.ToString();
}
}
}
AppleExtensions.cs
namespace AppleExtensionMethods
{
using System;
using ConsoleApplication1;
// Accessors for Seed Properties
public static class Seed
{
public static float GetSeedCount(this Apple apple)
{
return Convert.ToSingle(apple["SeedCount"]);
}
public static void SetSeedCount(this Apple apple, string count)
{
apple["SeedCount"] = count;
}
}
// Accessors for Skin Properties
public static class Skin
{
public static string GetSkinColor(this Apple apple)
{
return apple["Color"];
}
public static void SetSkinColor(this Apple apple, string color)
{
apple["Color"] = ValidSkinColorOrDefault(apple, color);
}
private static string ValidSkinColorOrDefault(this Apple apple, string color)
{
switch (color.ToLower())
{
case "red":
return color;
case "green":
return color;
default:
return "rotten brown";
}
}
}
}
Here is a test drive:
Program.cs
namespace ConsoleApplication1
{
using System;
using AppleExtensionMethods;
class Program
{
static void Main(string[] args)
{
Apple apple = new Apple();
apple.SetSkinColor("Red");
apple.SetSeedCount("8");
Console.WriteLine("My apple is {0} and has {1} seed(s)\r\n", apple.GetSkinColor(), apple.GetSeedCount());
apple.SetSkinColor("green");
apple.SetSeedCount("4");
Console.WriteLine("Now my apple is {0} and has {1} seed(s)\r\n", apple.GetSkinColor(), apple.GetSeedCount());
apple.SetSkinColor("blue");
apple.SetSeedCount("0");
Console.WriteLine("Now my apple is {0} and has {1} seed(s)\r\n", apple.GetSkinColor(), apple.GetSeedCount());
apple.SetSkinColor("yellow");
apple.SetSeedCount("15");
Console.WriteLine(apple.ToString());
// Unfortunatly there is nothing stopping users of the class from doing something like that shown below.
// This would be bad because it bypasses any behavior that you have defined in the get/set functions defined
// as extension methods.
// One thing in your favor here is it is inconvenient for user of the class to find the valid property names as
// they'd have to go look at the apple class. It's much easier (from a lazy programmer standpoint) to use the
// extension methods as they show up in intellisense :) However, relying on lazy programming does not a contract make.
// There would have to be an agreed upon contract at the user of the class level that states,
// "I will never use the indexer and always use the extension methods!"
apple["Color"] = "don't panic";
apple["SeedCount"] = "on second thought...";
Console.WriteLine(apple.ToString());
}
}
}
Addressing your comment from 7/11 (the date, not the store) :)
In the sample code you provided, there is a comment that states:
"As you can see, I can't call
BasicBroodmother methods on "monster"
You realize you could do something like this at that point:
BasicBroodmother bm = monster as BasicBroodmother;
if (bm != null)
{
bm.Eat();
}
There isn't much meat to your code, (I understand it was just an example), but when I look at it I get the feeling that you should be able to improve the design. My immediate thought was having an abstract class for broodmother which would contain default implementations of any attributes/actions that are common to all broodmothers. Then specialized broodmothers, like the magical broodmother, would contain any specialized attributes/actions specific to the magical broodmother, but also inherit from the abstract class and if necessary override the nessecary base attributes/actions.
I would take a look at the Strategy pattern for the design of the actions so that the actions (i.e. behaviours like eat, spawn, attack) can be swappable based the type of monster.
[edit 7/13]
Don't have time to go into details right now (need sleep), but I put together some sample code showing a different approach.
The code consists of:
Broodfather.cs - abstract class filled with all things common to different Broodfathers "types."
BasicBroodFather.cs - concrete class that inherits from Broodfather.
BroodfatherDecorator.cs - abstract class to be inherited by all Broodfather decorators.
MagicalBroodfather.cs - this class decorates/wraps a Broodfather with "magic"
BloodthirstyBroodfather.cs - this class decorates/wraps a Broodfather with "bloodthirst"
program.cs - demonstrates two examples: The first starts with a basic broodfather that gets wrapped by magic then by bloodthirst. The second starts with a basic broodfather and wraps it in the other order bloodthirst, then magic.
Maybe your methods are not were they are supposed to be?
If you separated the Seed class from the Apple class, why don't you move the methods that use the Seed information to the Seed class too?
If those methods need information on other Apple properties, you can pass it as a parameter.
By doing this, I guess you can eliminate the initialization checks...
This is a great book about how to solve this kind of problem:
Refactoring
My main goal: I want short code.
Options:
Rewrite all functions as static and create a class for each one.
Rewrite your codebase in Perl.
Remove all comments.
I am trying to create a web-based tool for my company that, in essence, uses geographic input to produce tabular results. Currently, three different business areas use my tool and receive three different kinds of output. Luckily, all of the outputs are based on the same idea of Master Table - Child Table, and they even share a common Master Table.
Unfortunately, in each case the related rows of the Child Table contain vastly different data. Because this is the only point of contention I extracted a FetchChildData method into a separate class called DetailFinder. As a result, my code looks like this:
DetailFinder DetailHandler;
if (ReportType == "Planning")
DetailHandler = new PlanningFinder();
else if (ReportType == "Operations")
DetailHandler = new OperationsFinder();
else if (ReportType == "Maintenance")
DetailHandler = new MaintenanceFinder();
DataTable ChildTable = DetailHandler.FetchChildData(Master);
Where PlanningFinder, OperationsFinder, and MaintenanceFinder are all subclasses of DetailFinder.
I have just been asked to add support for another business area and would hate to continue this if block trend. What I would prefer is to have a parse method that would look like this:
DetailFinder DetailHandler = DetailFinder.Parse(ReportType);
However, I am at a loss as to how to have DetailFinder know what subclass handles each string, or even what subclasses exist without just shifting the if block to the Parse method. Is there a way for subclasses to register themselves with the abstract DetailFinder?
You could use an IoC container, many of them allows you to register multiple services with different names or policies.
For instance, with a hypothetical IoC container you could do this:
IoC.Register<DetailHandler, PlanningFinder>("Planning");
IoC.Register<DetailHandler, OperationsFinder>("Operations");
...
and then:
DetailHandler handler = IoC.Resolve<DetailHandler>("Planning");
some variations on this theme.
You can look at the following IoC implementations:
AutoFac
Unity
Castle Windsor
You might want to use a map of types to creational methods:
public class DetailFinder
{
private static Dictionary<string,Func<DetailFinder>> Creators;
static DetailFinder()
{
Creators = new Dictionary<string,Func<DetailFinder>>();
Creators.Add( "Planning", CreatePlanningFinder );
Creators.Add( "Operations", CreateOperationsFinder );
...
}
public static DetailFinder Create( string type )
{
return Creators[type].Invoke();
}
private static DetailFinder CreatePlanningFinder()
{
return new PlanningFinder();
}
private static DetailFinder CreateOperationsFinder()
{
return new OperationsFinder();
}
...
}
Used as:
DetailFinder detailHandler = DetailFinder.Create( ReportType );
I'm not sure this is much better than your if statement, but it does make it trivially easy to both read and extend. Simply add a creational method and an entry in the Creators map.
Another alternative would be to store a map of report types and finder types, then use Activator.CreateInstance on the type if you are always simply going to invoke the constructor. The factory method detail above would probably be more appropriate if there were more complexity in the creation of the object.
public class DetailFinder
{
private static Dictionary<string,Type> Creators;
static DetailFinder()
{
Creators = new Dictionary<string,Type>();
Creators.Add( "Planning", typeof(PlanningFinder) );
...
}
public static DetailFinder Create( string type )
{
Type t = Creators[type];
return Activator.CreateInstance(t) as DetailFinder;
}
}
As long as the big if block or switch statement or whatever it is appears in only one place, it isn't bad for maintainability, so don't worry about it for that reason.
However, when it comes to extensibility, things are different. If you truly want new DetailFinders to be able to register themselves, you may want to take a look at the Managed Extensibility Framework which essentially allows you to drop new assemblies into an 'add-ins' folder or similar, and the core application will then automatically pick up the new DetailFinders.
However, I'm not sure that this is the amount of extensibility you really need.
To avoid an ever growing if..else block you could switch it round so the individal finders register which type they handle with the factory class.
The factory class on initialisation will need to discover all the possible finders and store them in a hashmap (dictionary). This could be done by reflection and/or using the managed extensibility framework as Mark Seemann suggests.
However - be wary of making this overly complex. Prefer to do the simplest thing that could possibly work now with a view to refectoring when you need it. Don't go and build a complex self-configuring framework if you'll only ever need one more finder type ;)
You can use the reflection.
There is a sample code for Parse method of DetailFinder (remember to add error checking to that code):
public DetailFinder Parse(ReportType reportType)
{
string detailFinderClassName = GetDetailFinderClassNameByReportType(reportType);
return Activator.CreateInstance(Type.GetType(detailFinderClassName)) as DetailFinder;
}
Method GetDetailFinderClassNameByReportType can get a class name from a database, from a configuration file etc.
I think information about "Plugin" pattern will be useful in your case: P of EAA: Plugin
Like Mark said, a big if/switch block isn't bad since it will all be in one place (all of computer science is basically about getting similarity in some kind of space).
That said, I would probably just use polymorphism (thus making the type system work for me). Have each report implement a FindDetails method (I'd have them inherit from a Report abstract class) since you're going to end with several kinds of detail finders anyway. This also simulates pattern matching and algebraic datatypes from functional languages.