Base class containing a generic instance created in derived class? - c#-4.0

I'm trying to figure out if this is possible.
I have a class, BaseGameEntity, from this I currently derive NormalDrop and OtherDrop each of which has an instance of a StateMachine< T > where T is NormalDrop and OtherDrop respectively.
From here relevant states can be called that apply to those kinds of drop.
What I want to do is put another layer in, the Drop class, which derives from BaseGameEntity which the other forms of drop then derive from.
Within Drop I want a StateMachine< T > where the "T" becomes NormalDrop or OtherDrop depending on what is using it as its base class.
Is this actually possible?

Yes, you can use the curiously recurring template pattern:
public class Drop<T> where T : Drop<T> { ... }
public class NormalDrop : Drop<NormalDrop> { ... }
public class OtherDrop : Drop<OtherDrop> { ... }
Then within the Drop base class T is always NormalDrop or OtherDrop.
This pattern generally isn't considered developer friendly as upon first glance it is confusing and there are probably better ways to structure code (though possibly not always). Eric Lippert wrote a very good blog post about this pattern and some of its shortcomings here.

Related

Puppet passing parameters from profile to module

I have a module "base" with an init.pp class which has some parameters as such:
class base (
$listen_ip = "xx.xx.xx.xx",
$listen_port = 3306,
$admin_username = 'admin',
$admin_password = 'admin',
)
{
...
}
Then I have created a profile "base" where I want to set some of the parameters:
class profile::base {
class { 'base':
$listen_ip = "xxx.xxx.xx.xx",
$listen_port => 6033,
}
}
Then the is a secondary profile where I want to set the username and password:
class profile::department::sales::base {
class { '::profile::base':
$admin_username = "some_user",
$admin_password => "some_pw",
}
}
However it's not possible to set the parameters from the "sales" profile.
The idea is that some values will be always the same for the base class and that some differ based on the department.
However it's not possible to set the parameters from the "sales" profile.
Not exactly. What is not allowed is using two different resource-like declarations for the same class while building one manifest. If you use even one then you must make certain that it is the first (or only) declaration of that class that the catalog builder evaluates.
To understand this, you need to appreciate that assigning parameter values is not the principal purpose of declarations such you are using. The principal purpose is rather to specify that the class in question should be included in the catalog in the first place. In service to that goal, values are bound to all the parameters of a class at the point where its first declaration is evaluated. Thus, your two class declarations do not supplement each other. Instead, they conflict with each other.
Even if the parameter values it specified for class base were identical to those declared by class profile::base, however, Puppet would still object to all uses of class profile::department::sales::base. To simplify evaluation and be absolutely certain to avoid inconsistency, it implements a stronger constraint than is actually required: that only the first-evaluated declaration of any given class may be a resource-like one.
Note: the latest docs actually specify an even stronger constraint than that: "Resource-like class declarations require that you declare a given class only once." In practice, however, this is a simplification (in every version of Puppet so far released since the introduction of parameterized classes). It is likely inspired by the fact that the order in which Puppet manifests are evaluated can be difficult to predict, so if you use include-like declarations along with a resource-like declaration of the same class, in different manifests, then it can be hard to ensure that the resource-like one is always evaluated first.
The idea is that some values will be always the same for the base
class and that some differ based on the department.
For most purposes it is best to avoid resource-like class declarations altogether, relying instead on external data (Hiera) for binding values to class parameters. Hiera recognizes a hierarchy of data sources (hence the name) and supports specifying different parameters at different levels, and even overriding data from one level at a higher-priority level.
My suggestion, then, is to leverage Hiera to assign appropriate parameter values to class base. There are many ways the specifics could play out.

Introspection: how do we get the name of a class within a class?

Say we have
class Foo {}
Is there a way to obtain "Foo" from within the class?
Yes.
class Foo {
say ::?CLASS.^name; # OUTPUT: Foo
}
Kaiepi's solution has its place, which I'll get to below, but also consider:
class Foo {
say Foo.perl; # Foo
say OUR.WHO; # Foo
::?PACKAGE
}
Foo.perl
This provides a simple answer to your literal question (though it ignores what you're really after, as explained in your comment below and as suggested by the metaprogramming tag and your use of the word "introspection").
OUR.WHO
I think this is typically more appropriate than ::?CLASS.^name for several reasons:
Looks less line-noisy.
Works for all forms of package, i.e. ones declared with the built in declarators package, module, grammar, or role as well as class, and also custom declarators like actor, monitor, etc.
Will lead readers to mostly directly pertinent issues if they investigate OUR and/or .WHO in contrast to mostly distracting arcana if they investigate the ::?... construct.
::?CLASS vs ::?PACKAGE
OUR.WHO only works in a value grammatical slot, not a type grammatical slot. For the latter you need a suitable ::?... form, eg:
class Foo { has ::?CLASS $bar }
And these ::?... forms also work as values:
class Foo { has $bar = ::?CLASS }
So, despite their relative ugliness, they're more general in this particular sense. That said, if generality is at a premium then ::?PACKAGE goes one better because it works for all forms of package.

UML - How to show a class instantiated by its static main method

It is a Sequence Diagram HowTo question, not a HowTo code.
I am using Visio 2010 and developing >> reverse engineering from Microsoft Dynamics AX 2012 / X++. Yes people its all about how to map static on UML.
My class is instantiated from FORM using at its void static main(). This calls another static method, say construct() which returns an instance of the same class.
I want to show the class (in static methods) and the resulting object separately some like the meta class runs (self msgs) and finally produces the class object which finally takes over. But how will a self msg call return a value ? How do I connect it with the resulting object of the class ? I hope I make enough sense to make you guys understand.
Note, the class is not a static class, but it has a static constructor.
If you want to depict a call to constructor (i.e. static operation that is responsible for creating an object and (usually) returning it as a reply) then you have to use a createMessage construct i.e. a dashed line with an open arrow and the word create on it. While this is not directly stated in specification, usually in such case the arrow points on the lifeline box (rectangle) rather than a line itself (however I've seen information that both notations are correct).
Note that in this case the logic of constructor is hidden (encapsulated) which is a good idea in general.
You can find more details in UML specification in section 17.4, especially 17.4.4.1 and an example in section 17.6.5 on Figure 17.14.
If you want to use a static operation other than constructor and call it without a use of class instance you have to model class as object (after all class is an object itself at least on analytical level). Note that the type of message can be either synchronous or asynchronous depending on your needs.
With this approach you can provide details on how the class handles this function (i.e. what other calls does it make).
For more details see "Applied UML and Patterns" by Craig Larman, section 15.4, Figure 15.20. Note however that Larman suggest a use of <<metaclass>> stereotype. Yet the called object is a class (metaclass is a class whose instance is class so this is not our case) so the stereotype should be <<class>>.

Interfacing and extending ApplicationClass

I am trying to write a module in F#, making it easier working with Excel, by extracting rows, columns, etc. along with type casting and so on. One of the first things I wanted to do, was to extend various classes/types to implement the IDisposable interface. I tried to write something like the following
type Excel.ApplicationClass with
interface IDisposable with
member this.Dispose() =
this.excel.Quit()
Marshal.ReleaseComObject(this.excel) |> ignore
What I wasn't aware of, was that I would get the following error "All implemented interfaces should be declared on the initial declaration of the type".
My question is the following: Since I am not allow to extend a type with an interface - what else could I do?
If you inherit from the base class it can work, like this
type myAppClass() =
inherit Excel.ApplicationClass() //may not be correct signature - you need to match the base constructor
interface IDisposable with
member this.Dispose() =
//function body

Why can't I add Contract.Requires in an overridden method?

I'm using code contract (actually, learning using this).
I'm facing something weird to me... I override a method, defined in a 3rd party assembly. I want to add a Contract.Require statement like this:
public class MyClass: MyParentClass
{
protected override void DoIt(MyParameter param)
{
Contract.Requires<ArgumentNullException>(param != null);
this.ExecuteMyTask(param.Something);
}
protected void ExecuteMyTask(MyParameter param)
{
Contract.Requires<ArgumentNullException>(param != null);
/* body of the method */
}
}
However, I'm getting warnings like this:
Warning 1 CodeContracts:
Method 'MyClass.DoIt(MyParameter)' overrides 'MyParentClass.DoIt(MyParameter))', thus cannot add Requires.
[edit] changed the code a bit to show alternatives issues [/edit]
If I remove the Contract.Requires in the DoIt method, I get another warning, telling me I have to provide unproven param != null
I don't understand this warning. What is the cause, and can I solve it?
You can't add extra requirements which your callers may not know about. It violates Liskov's Subtitution Principle. The point of polymorphism is that a caller should be able to treat a reference which actually refers to an instance of your derived class as if it refers to an instance of the base class.
Consider:
MyParentClass foo = GetParentClassFromSomewhere();
DoIt(null);
If that's statically determined to be valid, it's wrong for your derived class to hold up its hands and say "No! You're not meant to call DoIt with a null argument!" The aim of static analysis of contracts is that you can determine validity of calls, logic etc at compile-time... so no extra restrictions can be added at execution time, which is what happens here due to polymorphism.
A derived class can add guarantees about what it will do - what it will ensure - but it can't make any more demands from its callers for overridden methods.
I'd like to note that you can do what Jon suggested (this answers adds upon his) but also have your contract without violating LSP.
You can do so by replacing the override keyword with new.
The base remains the base; all you did is introduce another functionality (as the keywords literally suggest).
It's not ideal for static-checking because the safety could be easily casted away (cast to base-class first, then call the method) but that's a must because otherwise it would violate LSP and you do not want to do that obviously. Better than nothing though, I'd say.
In an ideal world you could also override the method and call the new one, but C# wouldn't let you do so because the methods would have the same signatures (even tho it would make perfect sense; that's the trade-off).

Resources