public enum RelationType { Subclass, HasArm, HasLeg };
public RelationType RelationShipType { get; set; }
public static IOwlRelation AddSubClassRelation(IOwlClass parent, IOwlClass child)
{
return new OwlRelation
{
Parent = parent,
Child = child,
RelationShipType = RelationType.Subclass
};
}
So let's say this was in a OwlRelation class and now in the consumer class first I create a OwlRelation object by saying like
OwlRelation r1 = OwlRelation.AddSubClassRelation( someParent, someChild);
and also have a method like AddRelation(OwlRelation) that I can pass that r1 object to it, now in the body of this method I can check and see what was the value of the enumeration on this object and some stuff based on that value.
So that's the reason I have defined that Enumeration type in the OwlRelation class. BUT I think this is not the correct way of axchieving this and prob I just don't have enough expertise to figure it out. So what do you think is the correct way of doing this?
You could implement different relation types as different classes.
public abstract class OwlRelation : IOwlRelation
{
// Implement infrastructure common to all relation types
}
public SubclassOwlRelation : OwlRelation
{
// Implement things specific to Subclass-relations
}
public HasArmOwlRelation : OwlRelation
{
// Implement things specific to HasArm-relations
}
...
With your implementation you are likely to run into code like this one
switch (relation.RelationshipType) {
case RelationshipType.Subclass:
DoSomeSubclassStuff(relation);
break;
case RelationshipType.HasArm:
DoSomeArmStuff(relation);
break;
case RelationshipType.HasLeg:
DoSomeLegStuff(relation);
break;
}
With an object-oriented approach the corresponding code looks like this
relation.DoSomeStuff();
I'm not sure what you are trying to do. From the other direction, the two correct ways to use an enum are:
You have a mutually-exclusive set of values, the total number of which are less than the integer-type you are basing the enum on (int is the default, long is the largest possible), and you can reasonably list every one of them (or expect users to know the number that corresponds with missing items, due to some external standard).
You have a non-mutually-exclusive set of values, which you can combine with binary operators so that if e.g. Read is 1, Write is 2 and Execute is 4, then the ability to read and excecute, but not write is 5 (1 | 4).
Now, I haven't looked at the Web Ontology Language (I'm guessing that's the sort of OWL you mean) in a long time, but I don't see how Arm and Subclass fits into this at all (nor remember anything about arms in OWL). But I also don't see how it fits into anything else - I don't see either the question "Is it an arm, or a subclass?" makes sense (which would fit enum-use 1) nor the question "Is it an arm, a subclass, or both, or neither?" makes sense (which would fit enum-use 2).
So, not much of an answer, but hopefully enough on using enum to help a bit.
I think it's a typical problem and it's solved by applying strategy pattern.
So it would be different RelationStrategy subclasses as #Olivier has suggested.
You can read about it here
Related
Hello denizens of stack overflow, I'm having an issue (perhaps with understanding?) regarding polymorphism and generics. I want to be able to define a "system" that contains a "component". I also want to be able to extend systems and components to be able to have greater functionality.
I currently have two base classes, Component, and I/A_ComponentSystem (For the sake of brevity, I'm not going to be showing any actual code, just definitions):
public abstract class Component { }
public interface IComponentSystem { }
public interface IComponentSystem<TComponent> : IComponentSystem
where TComponent : Component { }
// The following are what should should actually be inherited from
public abstract class AComponentSystem : IComponentSystem { }
public abstract class AComponentSystem<TComponent> : AComponentSystem
where TComponent : Component { }
Below is an example component/system created:
public abstract class ITag : Component { } // This is to allow generating the code in a different binary. Hard to explain in the question, I'll clarify if need be
public class Tag : ITag { }
public abstract class ITagSystem : AComponentSystem<ITag> { }
public class TagSystem : ITagSystem { }
Below are some excerpts of actually trying to use the code/morph between the different objects (please note that the code isn't meant to be used in this way, but I'm writing unit tests to ensure compatibility between layers)
// This is the main system that will be passed around
TagSystem tagSys = new TagSystem();
// This is OK
ITagSystem ITagSys = (ITagSystem)ITagSys;
// This is OK
AComponentSystem A_TagSys = (AComponentSystem)tagSys;
// This is OK
AComponentSystem<ITag> ATag_TagSys = (AComponentSystem<ITag>)tagSys;
// This is OK
IComponentSystem I_TagSys = (IComponentSystem)tagSys;
// This is OK
IComponentSystem<ITag> ITag_TagSys = (IComponentSystem<ITag>)tagSys;
// Even the following is OK (which is why I am confused)
IComponentSystem<Tag> new_ITag_TagSys = (IComponentSystem<Tag>)tagSys;
//***This is where it blows up*** (1)
AComponentSystem<Tag> new_ATag_TagSys = (AComponentSystem<Tag>)tagSys;
I have another interface/class, SystemManager, which is defined thusly:
public interface ISystemManager
{
TComponent AddNewComponentToEntity<TComponent, TComponentSystem>(Entity e) // Please don't ask about Entity, it shouldn't be required for this snippet and I already feel like I've posted a lot)
where TComponent : Component, new() // Required for some reason or I get an error
where TComponentSystem : IComponentSystem<TComponent>;
}
Now, the specific block of code that I have here will throw an error as well:
//*** blows up here as well ***(2)
ISystemManager sysMan = new SystemManager(); // defined elsewhere
sysMan.AddNewComponentToEntity<Tag, ITagSystem>(entity);
As far as the errors that I receive, error (1) is:
Cannot convert type 'TagSystem' to 'AComponentSystem<Tag>'
Error (2) is below:
The type 'ITagSystem' cannot be used as type parameter 'TComponentSystem' in the generic type or method 'ISystemManager.AddNewComponentToEntity<TComponent,TComponentSystem>(Entity)'. There is no implicit reference conversion from 'ITagSystem' to 'IComponentSystem<Tag>'.
Now, as far as my question goes, it is thusly:
Why can I not convert TagSystem to AComponentSystem<Tag>? This seems like a valid morph.
Why is ITagSystem not converting to IComponentSystem<Tag>? It appears that Tag should still conform to ITag, which is supported.
Is there any way I could change my hierarchy while preserving my need for that many layers of abstraction?
Thank you to anyone for reading this and assisting me.
Note: Yes, this is for an EntityFramework driven game engine. I'm building it mainly as an exercise for myself, and so I can quickly spin up 3d projects for myself. Yes, I've built a few game projects before, no I'm not interested in "finishing" a game, I'm just tinkering and having fun.
Without a simpler and yet more-complete code example, it's impossible to provide specific advice in your specific scenario. However, the basic problem is that the types are indeed not convertible, just as the compiler says.
Why can I not convert TagSystem to AComponentSystem<Tag>? This seems like a valid morph.
TagSystem doesn't inherit AComponentSystem<Tag>. It inherits AComponentSystem<ITag>. These two types are not actually the same. Just because Tag inherits/implements ITag, that does not mean that AComponentSystem<Tag> automatically inherits/implements AComponentSystem<ITag>. If it did, then that would mean that a method or property of AComponentSystem<Tag> that normally would return a value of type Tag, could wind up being used in a situation where a Tag value is expected, but some other implementation of ITag is actually returned. This is because you would be able to cast to AComponentSystem<Tag>, and then use that reference to return the non-Tag implementation of ITag, to some code that only wanted Tag.
This is bad for what I hope are obvious reasons, so the compiler doesn't allow you to do that.
Why is ITagSystem not converting to IComponentSystem<Tag>? It appears that Tag should still conform to ITag, which is supported.
Without a good Minimal, Complete, and Verifiable code example, it's difficult to answer this part of your question, as the types you've shown don't appear consistent with the code you've shown. ITagSystem is declared as inheriting AComponentSystem<ITag>, which in turn implements only IComponentSystem, not IComponentSystem<TComponent>.
So based on the code shown, there's no reason even naively to think that the conversion could work. But let's assume for a moment there's a typo in the type declarations you've shown. Then the answer is basically the same as above: implementing IComponentSystem<ITag> is not the same as implementing IComponentSystem<Tag>.
Is there any way I could change my hierarchy while preserving my need for that many layers of abstraction?
Possibly. It depends on what these types actually do. Since C# 4, we've been able to specify generic type parameters on interfaces with covariance and contravariance. With a type parameter thus restricted, and interface members to match, the interface then can support specific casting scenarios like you're trying to do.
But note that this only works when the interface members really are compatible with such conversions. The compiler still won't let you do anything unsafe.
There are a lot of questions on Stack Overflow already discussing this. Technically your question could even be considered a duplicate of those. I hope the above addresses your immediate concerns, and gives you enough information to do more research and see if generic interface variance will work in your situation. If you need more help, I recommend you post a new question and make sure to include a good MCVE that clearly illustrates your question in the simplest way possible.
TagSystem distantly inherits AComponentSystem<ITag>, but you are trying to convert it to AComponentSystem<Tag>. (Note the lack of an "I" in the generic type.) Those two generic types of AComponentSystem<> are completely different, and you cannot freely cast between the two.
Same as point 1, just because Tag is a child of ITag doesn't mean that IComponentSystem<Tag> is a child of IComponentSystem<ITag>.
The answer is almost certainly yes, though exactly how depends entirely on how you are going to use it. You might also want to ask yourself if you really need this many layers of abstraction.
To give a better example of my first point, take for example a common generic type: the List. If generics followed the same inheritance rules as normal classes, then List<Car> would be a subtype of List<Vehicle>. But the difference between the two is that the first list can only hold cars, while the second list can hold any vehicle. So if these lists were parent and child, you would be able to do the following:
List<Car> cars = new List<Car>();
List<Vehicle> vehicles = (List<Vehicle>)cars;
vehicles.Add(new Truck());
You see the problem? The general rules of inheritance just allowed us to add a non-Car object to out list of cars. Or they would, provided that is a legal cast, which it isn't. In reality, List<Car> and List<Vehicle> are not related in any way, but are actually completely separate classes with no direct relation whatsoever.
So I'm trying to convert an entity into a DTO using the exact same type. Both types (classes) are the exact same except they are in different namespaces.
Should I need to cast them when I reference either one from the other namespace?
Or should VS automatically know and recognize they are the exact same although in different files?
Thanks
namespace SomeInternetShoppingSite
{
public class Client
{
public int Id { get; }
public sprint FirstName { get; }
...
}
}
namespace SomeOnlineBankingSite
{
public class Client
{
public int Id { get; }
public sprint FirstName { get; }
...
}
}
Do you really think the following should be legal?
var bankClient = new SomeOnlineBankingSite.Client(...);
var shoppingClient = (SomeInternetShoppingSite.Client)bankClient;
Allthough both classes are identical they are two completely different abstractions of two very distinct concepts. Even if the compiler can easily enough figure out that the type definitions are the same, it has no right to allow an explicit or implicit conversion between the two; only the authors of the classes have the right to allow that conversion if they so wish to, implementing a cast operator, a static factory method or what have you.
Basically what you're describing is duck typing. The closest C# equivalent is the "dynamic" keyword but I don't think that's exactly what you're asking for.
As others have pointed out, C# does not, in general, follow the typing model you've described and you probably wouldn't want it to. As InBetween's example shows, there's a big difference between "same name," "same interface," and "same meaning."
To answer the question more directly, first, I seriously question the wisdom of having two identical classes in separate namespaces - it seems like a pretty clear violation of the Don't Repeat Yourself principal. With that said, if define an implicit conversion between them that should allow you to use them more or less interchangeably (although the downside to that is it could get confusing which of the two objects you're referring to; I'm inclined to say that it's a bad practice based on that fact along).
The following piece of C# code does not compile:
public class A
{
public interface B { }
}
public class C
: A,
C.B // Error given here: The type name 'B' does not exist in the type 'C'.
{ }
public class D : C.B // Compiles without problems if we comment out 'C.B' above.
{ }
This behaviour is correct according to the C# 4.0 specification (paragraph 10.1.4.1):
While determining the meaning of the direct base class specification A of a class B, the direct base class of B is temporarily assumed to be object. Intuitively this ensures that the meaning of a base class specification cannot recursively depend on itself.
My question is: why isn't this behaviour allowed?
Intellisense doesn't have a problem with it - although I know that doesn't say much, after witnessing Visual Studio crash when Intellisense tries to make sense of some evil class combination with variant generics.
Searching the internet for the above quote from the specification yields nothing, so I'm guessing this hasn't been brought up yet anywhere.
Why do I care? I designed the following piece of code:
// The next three classes should really be interfaces,
// but I'm going to override a method later on to prove my point.
// This is a container class, that does nothing except contain two classes.
public class IBagContainer<Bag, Pointer>
where Bag : IBagContainer<Bag, Pointer>.IBag
where Pointer : IBagContainer<Bag, Pointer>.IPointer
{
// This could be an interface for any type of collection.
public class IBag
{
// Insert some object, and return a pointer object to it.
// The pointer object could be used to speed up certain operations,
// so you don't have to search for the object again.
public virtual Pointer Insert(object o) { return null; }
}
// This is a pointer type that points somewhere insice an IBag.
public class IPointer
{
// Returns the Bag it belongs to.
public Bag GetSet() { return null; }
}
}
// This is another container class, that implements a specific type of IBag.
public class BinarySearchTreeContainer<Tree, Node> : IBagContainer<Tree, Node>
where Tree : BinarySearchTreeContainer<Tree, Node>.BinarySearchTree
where Node : BinarySearchTreeContainer<Tree, Node>.BinarySearchTreeNode
{
// This is your basic binary search tree.
public class BinarySearchTree : IBagContainer<Tree, Node>.IBag
{
// We can search for objects we've put in the tree.
public Node Search(object o) { return null; }
// See what I did here? Insert doesn't return a Pointer or IPointer,
// it returns a Node! Covariant return types!
public override Node Insert(object o) { return null; }
}
// A node in the binary tree. This is a basic example of an IPointer.
public class BinarySearchTreeNode : IBagContainer<Tree, Node>.IPointer
{
// Moar covariant return types!
public override Tree GetSet() { return null; }
// If we maintain next and prev pointers in every node,
// these operations are O(1). You can't expect every IBag
// to support these operations.
public Node GetNext() { return null; }
public Node GetPrev() { return null; }
}
}
Lo behold, we have achieved covariant return types! There is one small detail however.
Try instantiating a BinarySearchTree. To do that, we need to specify BinarySearchTreeContainer.BinarySearchTree for some suitable Tree and Node classes. For Tree, we'd like to use BinarySearchTree, for which we'd need to specify BinarySearchTreeContainer.BinarySearchTree... And we're stuck.
This is essentially the curiously recurring template pattern (CRTP). Unfortunately, we can't fix it as in CRTP:
public class BinarySearchTreeContainer
: BinarySearchTreeContainer
<BinarySearchTreeContainer.BinarySearchTree,
BinarySearchTreeContainer.BinarySearchTreeNode> { }
public class IBagContainer
: IBagContainer
<IBagContainer.IBag,
IBagContainer.IPointer> { }
(...)
BinarySearchTreeContainer.BinarySearchTree tree
= new BinarySearchTreeContainer.BinarySearchTree();
tree.Search(null);
IBagContainer.IBag bag = tree; // No cast!
//bag.Search(null); // Invalid!
//BinarySearchTreeContainer.BinarySearchTreeNode node
// = bag.Insert(null); // Invalid!
And we're back to my original question: the top two class definitions are not allowed by the C# specification. If this class definition was allowed, my binary search trees would be usable. Right now, they merely compile: they can't be used.
I have struggled with the issues you bring up for countless hours over the last few years. A detailed discussion of all the issues you raise would take me several hours to type up, so I'll just summarrize:
First, it turns out that even with that "temporarily assumed to be object" clause that Mads and I added to try and tighten up that section of the spec, this section of the spec is still not well-founded. The "how to bind a name to a type" bit of the specification assumes that all nesting and inheritance relationships are known and consistent at the point at which the lookup happens, but of course obviously that cannot be the case since the whole reason we are doing a name lookup in the first place is to determine a base type. If I had my notes with me I could give you a number of examples of crazy type hierarchies where combinations of generics, nestings, interfaces and base classes put the compiler into situations where how you determine what a given name means depends on the order in which you are figuring out the base classes.
Obviously that is not a good place to be. We do not want the meaning of a C# program to differ when you re-order the classes in a file!
Second, we are constrained by what can be represented in metadata.
Third, historically we have been constrained by what can be efficiently emitted into metadata. Previous versions of the metadata emitters had performance or correctness issues if you tried to emit derived types before base types or inner types before outer types. (I attempted in C# 4 to address this by writing a topological sorter that would find an efficient ordering if any existed, but the change proved to be sufficiently complicated and dangerous that we decided to not take the change until Roslyn. In Roslyn we are using a completely different emitter.)
Fourth, it is rare that these sorts of topologies turn up in real production code; you are apparently an exception to that rule.
Fifth, one of our major goals for the language is to make it a "pit of quality" language, where the features of the language lead one to write programs that are both correct and comprehensible. Allowing the sorts of crazy "curiously recurring" patterns that you see in C++ templates is explicitly not a goal of the C# language team. We're not interested in providing a theoretically complete type system; we're interested in making it easy to represent that an Employee is a kind of Person.
All of these factors are working against making circularities in base class and nested class relationships more legal. As much as I personally would enjoy the challenge of coming up with a well-founded system for resolving circularities in base types in a manner that does not break any existing code, it is not a high enough priority; we have a long list of stuff we want to improve for Roslyn, and the base class resolution algorithm is far from the top of that list.
I currently have
if A {
//code
return;
}
if B {
//code
return;
}
...
Is there a simple way to express this for a large number of conditions?
The goal in this case is validation of something that can fail in different ways, which all require different handling.
I then expect this block of code to be called again later, when whatever condition has just been resolved will fail, and it will slip through the tests until it meets another condition and is rejected in a new and exciting way.
I was really just hoping for something on the level of a switch statement (in terms of simplicity and ease of use) but I guess that doesn't exist...
Possibly, but it's really hard to guide you without knowing more about the types of conditions you have and what the code in each one does... if there are similarities, you can probably find ways to abstract those out instead of repeating them (using 'switch' statements, delegates, etc). If these things are totally unrelated, it won't get any better than what you have shown - except to change latter 'if's to 'else if' and then put a single 'return' at the very end.
If your conditions are testing the same value for equality with other values, you can use the switch statement. Note that in C#, unlike C++ or Java, you can use a string as the switch value.
You can use the ?: operator but only if your "code" can be expressed as a single expression and they all return the same type. So for example,
var user = conditionA ? expressionA :
conditionB ? expressionB :
conditionC ? expressionC;
It would probably help most though if you say what your actual problem is. It's possible a cleaner approach would be possible through polymorphism, array/dictionary lookups, etc.
You could use class that inherit an abstract base class ConditionalAction, which could look like this:
public abstract class ConditionalAction
{
public abstract bool Condition();
public abstract void Action();
}
A sample class that inherits ConditionalAction:
public class SampleConditionalAction : ConditionalAction
{
public override bool Condition()
{
// Condition
}
public override void Action()
{
// Code
}
}
Sample implementation:
List<ConditionalAction> conditionalActions = new List<ConditionalAction>();
conditionalActions.Add(new SampleConditionalAction());
// Add more ConditionalActions...
foreach(ConditionalAction conditionalAction in conditionalActions)
{
if (conditionalAction.Condition())
conditionalAction.Action();
}
The main place you'd get stuck with this approach is if you need information for your conditions or your actions, but you can build that in by passing in parameters to your constructors of your ConditionalActions.
You can create a Dictionary<Func<bool>, Action>. The keys will be the conditions (every one of them a bool Method()) and the values will be the pieces of code to execute.
Then you can easily iterate through the keys that meet the codition and execute their values:
foreach (pair in dictionary.Where(pair => pair.Key()))
{
pair.Value();
}
It depends what the conditionals are, the code is doing and the design of the component.
For example, if it's a configuration class that stores a load of settings then I'd have no problem with the above. Conversely if this defines or controls paths of execution in your application then that might suggest a design deficiency. Lots of conditionals or switch statements can be refactored using inheritance or dependency injection for example.
If you have a serious number of conditions and it isn't a config class I would think about your code at a design level, rather than a syntactic one.
My colleague and I have been having a discussion about what Collections should be called.
For example:
Class Product - Collection - Class Products
or
Class Product - Collection - Class ProductCollection
I've had a look around to see if I can see any guidelines or reasons for using one or the other but nothing seems to spring out. The framework seems to use both variants for example. The argument I can see is that a class that has a collection of products variable should be called Products but it should be of type ProductCollection.
Which is correct if any?
In the same vane is there a standard for the naming of return variable for a function. e.g. retVal?
We mainly code in C#, although I'm not sure that affects my question.
I would say that with generics there should rarely ever be a reason to create a custom collection type. But if you must I would say that ProductCollection would best fit the naming conventions of the framework.
Still, consider using a List<Product> or Collection<Product> or better yet IList<Product> or ICollection<Product>.
Edit: This is in response to MrEdmundo's comments below.
In your case you have two choices. The most obvious choice would be to use inheritance like this:
class Ball { }
class BallCollection : List<Ball>
{
public String Color { get; set; }
public String Material { get; set; }
}
I say obvious because it seems like the best idea at first glance but after a bit of thought it becomes clear that this is not the best choice. What if you or Microsoft creates a new SuperAwesomeList<T> and you want to use that to improve the performance of your BallCollection class? It would be difficult because you are tied to the List<T> class through inheritance and changing the base class would potentially break any code that uses BallCollection as a List<T>.
So what is the better solution? I would recommend that in this case you would be better off to favor composition over inheritance. So what would a composition-based solution look like?
class Ball { }
class BallCollection
{
public String Color { get; set; }
public String Material { get; set; }
public IList<Ball> Balls { get; set; }
}
Notice that I have declared the Balls property to be of type IList<T>. This means that you are free to implement the property using whatever type you wish as long as that type implements IList<T>. This means that you can freely use a SuperAwesomeList<T> at any point which makes this type significantly more scalable and much less painful to maintain.
Products is certainly not correct IMHO. A non-static class name should represent a noun (not plural), because you should be able to say "x is a [classname]".
Obviously, Products doesn't fit in that scheme. ProductCollection does:
Illustration:
var products = new Products(); // products is a Products
var products = new ProductCollection(); // products is a ProductCollection
Which one "sounds right" ?
Another thing about naming collection classes: I usually try to name collection classes in such way that it is clear what kind of collection it is.
For example:
class ProductCollection: can only be enumerated and the Count retrieved (i.e. only implements ICollection interface(s))
class ProductList: a list that can be manipulated using Add(), Insert(), etc. (i.e. implements IList interface(s))
class ProductDictionary: a dictionary of products accessible by some key (i.e. implements IDictionary interface(s))
The last one can be ambiguous if there could be a doubt what the key of the dictionary is, so it's better to specify what the key type is (like ProductDictionaryByString). But to be honest, I rarely name it this way because most of the time the key will be a string anyway.
The .NET Framework frequently uses a "Collection" postfix for its collection types. StringCollection, ObservableCollection, KeyedCollection, etc. So go with ProductCollection.
Noticed nobody answered you on the retVal stuff (Or I could just be getting blind). Although I'm not an expert; on the matter of the retVal issue I'm not 100% sure what you mean by "naming of return variable", but if you mean stuff like this:
public void GetSomething(out object retVal)
{
retVal = ThingFactory.CreateSomething();
}
I would say, no matter what the convention is, don't do it. It's very annoying. Just return the value instead. If you need to return more than one thing, then I would think the method either does more than one thing (which a method shouldn't) or those things should be wrapped up in some sort of logical class that could be returned instead.
If instead by "naming of return variable" you mean stuff like this:
var retVal = ThingFactory.CreateSomething();
Then I would say name the variable according to what it is. What it is going to be used for. If its a list of cars, call it listOfCars, if it's a piece of bread to be eaten later, call it pieceOfBread or pieceOfBreadToBeEatenLater.
Hope that helped and that it wasn't too far off into a field somewhere :p
Thesaurus.com
Look no further. No longer will you mull over pluralized singularity. Just fasten one of these plural-protectors to your object's name:
Jumble
Gob
Trove
Miscellany
Vocab
Load
Agglomeration
Mound
Series
Lexicon
Muster
Glossary
Hoard
Swarm
Group
Cluster
Convoy
Assemblage
Herd
Mob
Batch
Amassment
Pile
Bank
Congregation
Clump
Volume
Set
Reserve
Compilation
Flock
Army
Make it fun.