I want to create a nested structure where every class represents a country, inheriting the same parent class Country. Each child class should have an enum representing the different states States.
The goal is being able to select a country, then one of its states.
The Content will be saved into a dictionary Dictionary<Tuple<string, Type>, object> where the Types would be Country and Country.States.
I tried making an interface/abstract class with an enum called States to be implemented, but this does not work, as it is a type definition.
Is there any workaround?
public abstract class Country
{
public abstract enum States { get; }
}
public class CountryA : Country
{
public new enum States
{
StateA,
StateB,
StateC,
}
}
Your design is flawed, you need to create a single Country class with a property e.g. public string[] States { get; set; }.
Then create instances (objects) of your Country class, each with States set to the items that are needed:
var usa = new Country { Name = "USA", States = new[] { "Alabama", ... } };
var canada = new Country { Name = "Canada", States = new[] { ... } };
// etc
You have a few options:
You can create an enum at runtime (see here: Dynamically create an enum), but I don't think that'll suit your needs, as I imagine you're going down the enum route for ease of use in coding than anything else.
You could implement a typesafe enum pattern (see here: typesafe enum pattern), but that's even more coding just for the ability to use a design that mimics enums while your coding the rest of your logic.
My advice is to use a dictionary and build your 'states' at instantiation from a settings file or external data source. After all, countries and their states/cities/etc do change names from time to time. Locking yourself into a hard-coded situation like what you're aiming for isn't going to support such future changes.
Good luck!
[Edited following response from camilo-terevinto]
While I certainly agree that your design is most likely flawed, since you'd need hundreds of classes and enums, I disagree entirely with the other answers that "it is not possible".
It's certainly possible using generics (while keeping in mind you cannot restrict entirely to Enums):
public abstract class Country<TStates>
where TStates: struct, IConvertible, IFormattable, IComparable
{
public abstract TStates[] States { get; }
}
public enum UnitedStatesStates
{
WhoCares, WhoCares2
}
public class UnitedStatesCountry : Country<UnitedStatesStates>
{
public override UnitedStatesStates[] States { get; }
}
Now, I highly doubt this will be useful in the (not-so-long) term.
You are asking to make enum inheritable, this is possible to achieve if you don't use enum, but a class with static public members (which can be inherited and have different set of members per type). It behave nearly as enum:
public class Country1
{
public static State State1 { get; } = new State("State 1");
public static State State2 { get; } = new State("State 2");
...
}
It should be clear what Country1.State1 is, right? The State can be a more complex object than just a string. It doesn't require inheritance as you can see, because country define states as different members.
You can follow same principle to implement long chain of objects: Planet.Continent.Country.State.Province.Town.Street.Hause..
You say
Content will be saved into a dictionary Dictionary<Tuple<string, Type>, object> where the Types would be Country and Country.States.
Don't. Those are different types, that's a poor choice of a key. If you need to enumerate (to find) states, then just add another member to a Country:
public static IEnumerable<State> States
{
get
{
yield return State1;
yield return State2;
...
}
}
Then the searching for something can be a simple linq:
var stateAInCountry1 = ...Countries.OfType<Contry1>().Single().States.Single(o => o.Name == "A");
var countriesWithStateA = ...Countries.Where(o => o.States.Any(o => o.Name == "A"));
Not sure what problem are you solving by introducing a dictionary, but you can initialize additional data structure with proper key if you provided a way to iterate with easy.
It is not so clear to me, if there is anything else you want to achieve, besides being reminded by the compiler to define these different (!) enums.
Actually they have nothing in common to begin with, so neither the compiler nor you can draw any advantage of that contract.
What you could do is declare it as
public abstract string[] States {get;}
and obtain these strings from the individual enums you define in the derived classes. Then the common thing would probably be that you want the string result for informative purposes or something.
Related
In my C# testing, I often want to compare two objects of the same type (typically an expected object against the actual object), but I want to allow for some flexibility. For example, there may be timestamp fields that I know can't be equal or some fields that I just want to ignore when comparing the objects.
Most importantly, I want to provide an informative message that describes where the two object properties' values differ in order that I can quickly identify what the problem is. For example, a message that says "Source property Name value Fred does not match target property Name value Freda".
The standard Equals and Comparer methods just seem to return ints or Booleans which don't provide enough information for me. At the moment, my object comparison methods return a custom type that has two fields (a boolean and a message), but my thinking is that there must be a more standard way to do this. These days, perhaps a Tuple might be the way to go, but I would welcome suggestions.
"Comparison" might not be the word for what you're trying to do. That word already has a common meaning in this context. We compare objects for equality, which returns a boolean - they are equal or they are not. Or we compare them to see which is greater. That returns an int which can indicate that one or the other is greater, or that they are equal. This is helpful when sorting objects.
What you're trying to do is determine specific differences between objects. I wouldn't try to write something generic that handles different types of objects unless you intend for them to be extremely simple. That gets really complicated as you get into properties that return additional complex objects or collections or collections of complex objects. It's not impossible, just rarely worth the effort compared to just writing a method that compares the particular type you want to compare.
Here's a few interfaces and classes that could make the task a little easier and more consistent. But to be honest it's hard to tell what to do with this. And again, it gets complicated if you're dealing with nested complex properties. What happens if two properties both contain lists of some other object, and all the items in those lists are the same except one on each side that have a differing property. Or what if they're all different? In that case how would you describe the "inequality" of the parent objects? It might be useful to know that they are or are not equal, but less so to somehow describe the difference.
public interface IInstanceComparer<T>
{
IEnumerable<PropertyDifference> GetDifferences(T left, T right);
}
public abstract class InstanceComparer<T> : IInstanceComparer<T>
{
public IEnumerable<PropertyDifference> GetDifferences(T left, T right)
{
var result = new List<PropertyDifference>();
PopulateDifferences(left, right, result);
return result;
}
public abstract void PopulateDifferences(T left, T right,
List<PropertyDifference> differences);
}
public class PropertyDifference
{
public PropertyDifference(string propertyName, string leftValue,
string rightValue)
{
PropertyName = propertyName;
LeftValue = leftValue;
RightValue = rightValue;
}
public string PropertyName { get; }
public string LeftValue { get; }
public string RightValue { get; }
}
public class Animal
{
public string Name { get; }
public int NumberOfLimbs { get; }
public DateTime Created { get; }
}
public class AnimalDifferenceComparer : InstanceComparer<Animal>
{
public override void PopulateDifferences(Animal left, Animal right,
List<PropertyDifference> differences)
{
if(left.Name != right.Name)
differences.Add(new PropertyDifference("Name", left.Name, right.Name));
if(left.NumberOfLimbs!=right.NumberOfLimbs)
differences.Add(new PropertyDifference("NumberOfLimbs",
left.NumberOfLimbs.ToString(),
right.NumberOfLimbs.ToString()));
}
}
You could use extension methods to do this. For example:
public static Extensions
{
public static void CompareWithExpected(this <type> value, <type> expected)
{
Assert.AreEqual(expected.Property1, value.Property1, "Property1 did not match expected";
Assert.AreEqual(expected.Property2, value.Property2, "Property2 did not match expected";
}
}
Then this can be used as follows:
public void TestMethod()
{
// Arrange
...
// Act
...
// Assert
value.CompareWithExpected(expected);
}
You could have any number of these extension methods allowing you the flexibility to check only certain values etc.
This also means you do not need to pollute your types with what is essentially test code.
I have data from multiple organisations (police, fire, office) that need output in different formats.
To achieve this, I defined the following (this is a little simplified):
Transaction class -
"Success" indicator - Boolean.
"Type of department"- String or Enum.
A class which can be of any type - Police, Fire or Office (My question is on this as you will see).
A GenerateOutput() method - to handle generation of file formats.
Police class
Age - String
VehicleNumber - Integer
Supervisor - String
Fire class
Name - String
FireEngineNumber - Integer
County - Enum
WorkTimings - Enum
Office Class
Age - String
DeskNumber - Integer
Department - String
PayScale - Enum
IsManagement - Bool
As you can see, the Police, Fire and Office classes dont share anything in common and are primarily intended as data carrying entities. I intend to use a Factory to return an appropriate generic (not a C# generic) Transaction object with the data (Transaction object with Police, Fire or Office data within it) and then pass the returned object to a Strategy pattern which determines the file format (CSV, Excel, or XML; specified in a configuration file) each one needs.
My problem is in the definition of the Transaction object.
What type does the class in "3." of the Transaction class need to be? The data for each org differs, there are no common members, I am unable to define a common class for all.
Is the overall design appropriate? What other designs should I consider?
Based on Peter's comments below:
I think using generics might work, I ran into a problem though. I would like to use a factory to return the object requested, using GetTransactionObject, as below. What should be the return type of GetTransactionObject to accomodate this.
class TransactionFactory
{
Dictionary<string, Type> typeClassLookup;
public TransactionFactory()
{
typeClassLookup = new Dictionary<string, Type>();
typeClassLookup.Add("Police", typeof(PoliceData));
typeClassLookup.Add("Fire", typeof(FireData));
}
Transaction<????> GetTransactionObject(string org)
{
if( typeClassLookup.TryGetValue(org, out typeValue))
{
switch (typeValue.ToString())
{
case "policeData":
transactionObject = new Transaction<PoliceData>() { Data = new PoliceData(), params = null};
case "FireData":
transactionObject = new Transaction<FireData>() {Data = new FireData(), params = null};
}
}
return transactionObject;
If the types really have nothing in common, then you need no explicit base class. System.Object suffices, just as with many other generic types (i.e. any generic type lacking a constraint).
In other words, you could declare as:
class Transaction<T>
{
public bool Success { get; private set; }
public T Entity { get; private set; }
public Transaction(bool success, T entity)
{
Success = success;
Entity = entity;
}
public void GenerateOutput() { /* something goes here */ }
}
Personally, I would avoid adding a "department type" member. After all, that's implicit from the type parameter T. But you could add that easily to the above if you want.
If and when you find that the types do have something in common, such that your Transaction<T> type needs to do more than simply hold onto an instance of one of those types (which is about all it can do without a constraint), then you will be able to put that commonality into an interface or base class (depending on the specific need), and specify that in a constraint for the Transaction<T> class.
Note that it's not clear what you mean for the GenerateOutput() to do, or how it should work. But assuming that you want output that is specific for each Entity value, it seems to me that that is your "something in common". I.e., it's not the Transaction<T> class at all that needs to implement that method, but rather each entity type. In that case, you have something like this:
interface IDepartmentEntity
{
void GenerateOutput();
}
class Office : IDepartmentEntity
{
public void GenerateOutput() { /* department-specific logic here */ }
}
// etc.
Then you can declare:
class Transaction<T> where T : IDepartmentEntity
{
public bool Success { get; private set; }
public T Entity { get; private set; }
public Transaction(bool success, T entity)
{
Success = success;
Entity = entity;
}
public void GenerateOutput() { Entity.GenerateOutput(); }
}
EDIT:
Per Prasant's follow-up edit, with a request for advice on the GetTransactionObject()…
The right way to do this depends on the caller and the context, a detail not provided in the question. IMHO, the best scenario is where the caller is aware of the type. This allows the full power of generics to be used.
For example:
class TransactionFactory
{
public Transaction<T> GetTransactionObject<T>()
where T : IDepartmentEntity, new()
{
return new Transaction<T>()
{
Data = new T(),
params = null
}
}
}
Then you call like this:
Transaction<FireData> transaction = factory.GetTransactionObject<FireData>();
The caller, of course already knowing the type it is creating, then can fill in the appropriate properties of the transaction.Data object.
If that approach is not possible, then you will need for Transaction<T> itself to have a base class, or implement an interface. Note that in my original example, the IDepartmentEntity interface has only one method, and it's the same as the GenerateOutput() method in the Transaction class.
So maybe, that interface is really about generating output instead of being a data entity. Call it, instead of IDepartmentEntity, something like IOutputGenerator.
In that case, you might have something like this:
class Transaction<T> : IOutputGenerator
{
// all as before
}
class TransactionFactory
{
public IOutputGenerator GetTransactionObject(string org)
{
if( typeClassLookup.TryGetValue(org, out typeValue))
{
switch (typeValue.ToString())
{
case "policeData":
transactionObject = new Transaction<PoliceData>() { Data = new PoliceData(), params = null};
case "FireData":
transactionObject = new Transaction<FireData>() {Data = new FireData(), params = null};
}
}
return transactionObject;
}
}
This is an inferior solution, as it means the caller can only directly access the IOutputGenerator functionality. Anything else requires doing some type-checking and special-case code, something that really ought to be avoided whenever possible.
Note: if the Transaction type has other members which, like the GenerateOutput() method, are independent of the contained type T here, and which would be useful to callers who don't know T, then a possible variation of the above is to not reuse the interface used for the department-specific data types, but instead declare a base class for Transaction<T>, named of course Transaction, containing all those members not related to T. Then the return value can be Transaction.
What type does the class in "3." of the Transaction class need to be?
To decouple your department classes from the various export types, I recommend you make the department classes implement a common interface. Something like this:
public interface Exportable {
// return a list of attribute names, values, and types to export
IList<Tuple<String, String, Type>> GetAttributes();
}
For example:
public class Police : Exportable {
public IList<Tuple<String, String, Type>> GetAttributes() {
// return list size 3 - attribute info for Age, VehicleNumber, Supervisor
}
}
Is the overall design appropriate? What other designs should I consider?
The Transaction class design doesn't seem well suited for this problem.
Consider an Export class with a method for each export type, each method which receives the attributes returned from the Exportable interface method. Basic outline:
public static class Export {
public static boolean CSV(IList<Tuple<String, String, Type>> attributes) {
// export attributes to CSV, return whether succeeded
}
public static boolean Excel(IList<Tuple<String, String, Type>> attributes) {
// export attributes to Excel, return whether succeeded
}
// same thing for XML
}
I needed a structure that contains a pair of values, of which ones value would be changed. So my first thought was to use a KeyValueItem or a Tupple<,> but then I saw that they have only a getter. I can't realize why? What would you use in my case? I could create my own class, but is there any other way?
They are immutable types. The idea of immutable types is that they represent a value, and so cannot change. If you need a new value, you create a new one.
Let's say the first value of your tuple needs to change, just do this:
myValue = Tuple.Create(newValue, myValue.Item2);
To understand why immutability is important, consider a simple situation. I have a class that say contains a min and max temperatures. I could store that as two values and provide two properties to access them. Or I could store them as a tuple and provide a single property that supplies that tuple. If the tuple were mutable, other code could then change these min and max values, which would mean the min and max inside my class will have changed. By making the tuple immutable, I can safely pass out both values at once, secure in the knowledge that other code can't tamper with them.
You can create your own implementation:
public class Pair<T, U> {
public Pair() {
}
public Pair(T first, U second) {
this.First = first;
this.Second = second;
}
public T First { get; set; }
public U Second { get; set; }
};
Tuples are read only in C#. This is explained in the answer here, mainly due to their nature from functional programming.
You should create your own MutableTuple implementation that allows modification.
Things to consider:
You might want to override Equals and GetHashCode
You might want it to be sortable on the First element of the tuple (IComparable).
Tuples historically come from functional programming, where everything is supposed to be immutable. You can learn more about functional programming here:
Functional Programming
What are the benefits of functional programming?
And to have benefits of the historical approach, Tuples in C# have been designed the same way. If you really want mutable tuples, you can easily implement that yourself:
public class MutableTuple<TFirst, TSecond>
{
public TFirst { get; set; }
public TSecond { get; set; }
}
I have a naming problem for some of my classes. I need to wrap some primitive .net types into a class like the following. There will be about 20 of such classes.
(The naming is crap, of course. Just for a demonstrative purpose)
public class Int32Single
{
public int Value { get; set; }
}
public class Int32Double
{
public int Value1 { get; set; }
public int Value2 { get; set; }
}
public class DoubleSingle
{
public double Value { get; set; }
}
I can't use a generic approach for this.
How should I name such wrapper classes, where each class name should provide the necessary information which primite types are wrapped and in which quantity?
It might also be possible that I have class that contains mixed primite types.
This doesn't seem like a very good idea at all. You have both the Tuple class and a standard array available, that both make more sense in any conceivable use case. However, that doesn't answer your question, so...
The most intuitive name for a wrapper class would follow the convention of {type-name}Wrapper, or for example, Int32Wrapper. In your case, the wrapped object is a primitive type, so makes sense to call the class a "Tuple". Since you want to specify the size of the Tuple in your class name, {primitive-type-name}{size}Tuple seems like the most intuitive naming convention but this causes several problems.
The natural language used to describe Tuples create ambiguity (such as Single and Double because they conflict with the Type names). (e.g. DoubleDouble is bad)
Integers are used in the naming of some primitive types so this could cause ambiguity. (e.g. Int322Tuple is bad).
We can't move the size to the beginning such as 2Int32Tuple because integers are not valid characters to begin a class name. So, There are two approaches that I think could work.
I think your best bet to get around these constraints, is to use a {primitive-type-name}{text-represented-size}Tuple convention. (e.g. Int32TwoTuple or DoubleTwoTuple). This convention expresses the contents of the wrapper class without ambiguity, so it seems like a good approach. In addition the name begins with the primitive type name, so, if you have a lot of these classes, it will be easier for your IntelliSense to fill in the correct class name, and it will alphabetically be listed next to the primitive type that is being wrapped.
Generics can help you out here:
public class WrapTwo<T>
{
public T Value1 { get; set; }
public T Value2 { get; set; }
}
public class WrapOne<T>
{
public T Value1 { get; set; }
}
And have you considered the Tuple class?
OneInt32, TwoInt32s, TwoDoubles? Doesn't sound great.
Tuples? http://www.dotnetperls.com/tuple
I don't very fond of Tuples or arrays, because both don't tell much about their purpose. Well, I use them. But mostly as internal members of classes, local variables, or with 3rd party/legacy code.
Back to naming. Compare:
Tuple<int,int> a = Tuple.Create(10,10);
Int32Double b = new Int32Double(15, 15);
WrapTwo<int> c = new WrapTwo<int>(20, 20);
With
Point a = new Point(10, 10);
Vertex b = new Vertex(15, 15);
One can argue, that 'a' is not good name for variable (and suggest to use 'pointA' instead). But I think it's pretty good in context of geometry application.
Not just type name and creation code looks obscure, but consider type fields names:
a.X = 20;
b.Value1 = 20;
So, I think you need some self-descriptive type in context of your application domain.
Is there a way to collect (e.g. in a List) multiple 'generic' objects that don't share a common super class? If so, how can I access their common properties?
For example:
class MyObject<T>
{
public T Value { get; set; }
public string Name { get; set; }
public MyObject(string name, T value)
{
Name = name;
Value = value;
}
}
var fst = new MyObject<int>("fst", 42);
var snd = new MyObject<bool>("snd", true);
List<MyObject<?>> list = new List<MyObject<?>>(){fst, snd};
foreach (MyObject<?> o in list)
Console.WriteLine(o.Name);
Obviously, this is pseudo code, this doesn't work.
Also I don't need to access the .Value property (since that wouldn't be type-safe).
EDIT: Now that I've been thinking about this, It would be possible to use sub-classes for this. However, I think that would mean I'd have to write a new subclass for every new type.
#Grzenio
Yes, that exactly answered my question. Of course, now I need to duplicate the entire shared interface, but that's not a big problem. I should have thought of that...
#aku
You are right about the duck typing. I wouldn't expect two completely random types of objects to be accessible.
But I thought generic objects would share some kind of common interface, since they are exactly the same, apart from the type they are parametrized by. Apparently, this is not the case automatically.
I don't think it is possible in C#, because MyObject is not a baseclass of MyObject. What I usually do is to define an interface (a 'normal' one, not generic) and make MyObject implement that interface, e.g.
interface INamedObject
{
string Name {get;}
}
and then you can use the interface:
List<INamedObject> list = new List<INamedObject>(){fst, snd};
foreach (INamedObject o in list)
Console.WriteLine(o.Name);
Did it answer your question?
C# doesn't support duck typing. You have 2 choices: interfaces and inheritance, otherwise you can't access similar properties of different types of objects.
The best way would be to add a common base class, otherwise you can fall back to reflection.