I have a set of class objects that I can not touch. All of them have an ID property that I would like to access in other functions in a generic way.
For simplicities sake here is an example of my problem.
class Example1 {
int ID { get; set;}
}
class Example2 {
int ID { get; set; }
}
I am not able to edit either of these two classes or the library they are in.
I also have a function that expects an ID that can come from either Example1 or Example2. In order to handle this I have come up with a number of solutions but am curious what the proper way to solve this would be.
I could:
Use dynamic classes to access the various classes ID's.
Use reflection to pull out an ID parameter from any given type.
Use an odd inheritance by creating a new class so that Example1ViewModel : Example1, IIdentifiableObject and then expect IIdentifiableObject in my function and implement a copy constructor in Example1ViewModel to handle collecting the data
Write a separate filter function that can extract out the relevant parts from either class and provide the results.
None of these solutions seem particularly good to me. How should I be handling a many to one relationship like this in code and are there tools that C# provides to handle this?
possible solution using extension methods for the classes
public static class MyExtensions
{
public static int GetId(this Example1 ex)
{
return ex.Id;
}
public static int GetId(this Example2 ex)
{
return ex.Id;
}
}
You can add a static method using reflection:
public static int GetId(object obj)
{
Type type = obj.GetType();
return Convert.ToInt32(type.GetProperty("ID").GetValue(obj, null));
}
Then you can invoke it with any object to get the id property value.
Here is the solution that we ended up using and why.
We are using an inheritence structure that that takes the following two base classes:
FooExample
BarExample
and wraps them in the following
IExample
FooExampleModel : IExample
BarExampleModel : IExample
Both FooExampleModel and BarExampleModel have constructors which accept the class they are wrapping.
The importance of this is that it allows us to create methods accepting IExample instances without having to manipulate data beforehand. Additionally, unlike using dynamic types or reflection this solution provides us with compile time error checking.
Unfortunately using extension methods does not work. While it allows us to call the same method on two different object types like we wanted it does not allow those objects to be passed as Generic types to a seperate function.
The result of all of this is that this is now possible:
var foos = new List<FooExample>(); //Pretend there is data here
var bars = new List<BarExample>();
var examples = foos.Select((foo) => (IExample)new FooExampleModel(foo))
.Concat(bars.Select((bar) => (IExample)new BarExampleModel(bar)))
.ToList(); // Force evaluation before function call
DoSomethingOnIExamples(examples);
Besides that slightly gross LINQ query this appears to be the best way to accomplish this (DoSomethingOnIExamples(...) is a function accepting an IEnumerable<IExample> argument). Obviously this solution gets less nice as more types are added to this mix.
Related
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
}
Let's say I have an interface called IConvertableModel and it helps me to convert some MVC models to/from DTO objects as shown below:
public class DisplayEditModel : IConvertableModel<Display>
{
[HiddenInput(DisplayValue = false)]
public int ObjectId { get; set; }
[StringLength(255)]
public string Description { get; set; }
public Display ToDto()
{
return new Display
{
Description = Description,
ObjectId = ObjectId,
};
}
public void SetFromDto(Display dto)
{
Description = dto.Description;
ObjectId = dto.ObjectId;
}
}
But there is one problem with this approach and that is it doesn't allow me do this :
var dto = _dtoRepository.GetFirstDto();
return new DisplayEditModel().SetFromDto(dto);
Instead I should do the following:
var dto = _dtoRepository.GetFirstDto();
var model = new DisplayEditModel();
model.SetFromDto(dto);
return model;
and this is adding extra two lines of code and little bit complexity in the long run.
What I am thinking is to convert SetFromDto method to something like this:
public DisplayEditModel SetFromDto(Display dto)
{
Description = dto.Description;
ObjectId = dto.ObjectId;
return this;
}
I think the benefit of this code is obvious but I also like to learn whether this harms code readability and leads to unexpected results for developers in the long run and if you think anything else, what would you recommend.
Note: Because of the interfaces reasons, I am not thinking to implement a constructor method.
A few thoughts, to begin with:
Adding lines of code is not the same as adding complexity. Having three statements, where each does a simple operation, is not necessarily harder to maintain or understand than a single statement with three operations inside of it.
When a method that begins with Set..., programmers will automatically assume that some stateful values of the target object are going to be changed by this method. It is rare for Set methods to have a return value. Property setters in C# actually "return" the original value passed into them, so you can chain setters:
int i = foo.A = 2;
So the precedent is generally against returning "this" from a set method specifically.
Chaining in general is most useful/desired when you're expecting several operations to be performed, one after the other. For example, C# provides nice initialization syntax so you can "chain" a bunch of different property setters on the same object:
var foo = new Foo { A = 1, B = 2 };
You can see how chaining is fulfilling the need to perform similar, grouped, repetitive operations that typically get performed all together. That is not the problem that you are trying to solve.
If your main gripe is that you don't like having three lines of code, why not just use a helper whose name indicates what you're trying to do?
TModel MapToModel<TModel, TDto>(TDto dto, TModel model)
where TModel : IConvertableModel<TDto>
{
model.SetFromDto(dto);
return model;
}
// usage:
var dto = _dtoRepository.GetFirstDto();
return MapToModel(dto, new DisplayEditModel());
... or even:
TModel CreateModel<TModel, TDto>(TDto dto)
where TModel : IConvertableModel<TDto>, new()
{
var model = new TModel();
return MapToModel(dto, model);
}
// usage:
var dto = _dtoRepository.GetFirstDto();
return CreateModel<DisplayEditModel>(dto);
This is simple, readable, and feasible, whereas the approach you're suggesting would break the IConvertableModel<Display> interface:
public interface IConvertableModel<TDto>
{
public TDto ToDto();
public ??? SetFromDto(TDto dto);
}
What would SetFromDto return? You would have to define another generic type on IConvertableModel.
public interface IConvertableModel<TDto, TModel> {
public TDto ToDto();
public TModel SetFromDto(TDto dto);
}
But this wouldn't really indicate that the SetFromDto method is necessarily returning itself, because it allows for a class that is not a TModel to implement IConvertableModel to convert between two other types.
Now, you could go out of your way to push the generics even farther:
public interface IConvertableModel<TDto, TModel>
where TModel : IConvertableModel<TDto, TModel>
{...}
But this still allows for some fudging, and the interface cannot guarantee that you are really returning "this" object. All in all, I'm not a big fan of that approach.
Rather than having DisplayEditModel have a get/set method for a Display object to get/set the values, just use a property that doesn't actually have a separate backing store:
public Display Display
{
get
{
return new Display
{
Description = Description,
ObjectId = ObjectId,
};
}
set
{
Description = value.Description;
ObjectId = value.ObjectId;
}
}
Now you can use an object initializer with this property when creating a model:
return new DisplayEditModel() { Display = dto };
This is a very javascript way of approaching this problem, though it has it's benefits. In the context of C#, it is a little bit strange though libraries such as LINQ do this to allow chaining together function calls.
My only worry about this, is that this has to be a class that does this consistently. Implementing a chaining function return pattern is not really a convenience as much as it is a design choice. The rule to follow in this case, would be to return this every time you mutate the object.
Chaining also may not be worth it performance wise. Something that can be done by wrapping all those operations into a single function is much faster. For instance:
MyVector.setX(1).SetY(1).SetZ(1).SetW(0)
is a lot slower than simply
MyVector.set(1, 1, 1, 0)
because now you are now doing excessive stack operations to do something fairly simple. It only becomes worth it on very large operations that take up the bulk of the computing time and make sense to chain together. For this reason, LINQ allows you to chain things together.
I wouldn't say that it necessary "harms" or is dangerous. We are in the world of a managed language, so we don't have direct access to that memory location (unlike C/C++). So I would just call it a design choice which can be fairly powerful in some cases and not so much in others.
As noted, chainable methods work fine but are not as common in C# as in some other languages. If the extra lines of code only happen in one place, I'd just leave it alone. If it's really bugging you or you do it a lot, then consider implementing a special constructor for it:
public void DisplayEditModel(Display dto)
{
this.SetFrom(dto);
}
or a static factory method:
public static DisplayEditModel CreateFrom(Display dto)
{
var model = new DisplayEditModel();
model.SetFrom(dto);
return model;
}
Either option has a clear intent, lets you create and return the object in a single line, and is idiomatic. It does require a few extra lines of code in DisplayEditModel, but I doubt it will be a serious problem.
Basically, I would like to create a Method, that takes a base-class as a parameter, and can be used "generic" for derived classes
ef-code-first classes:
the base class
public abstract class BaseClass
{
public int Id { get; set; }
public string Name { get; set; }
}
derived classes:
public class DerivedA:BaseClass
{
public string AValue {get;set;}
...more specific fields
}
public class DerivedB:BaseClass
{
public string BValue {get;set;}
..... more specific fields
}
I call a "generic Method" with these slightly different objects:
System.Data.Entity.DbSet<DerivedA> _dA....
System.Data.Entity.DbSet<DerivedB> _dB....
genericMethod(_dA.Where(a => a.Name.StartsWith("a name")))); //<-contains records
genericMethod(_dB.Where(a => a.Id==5)); //<---- contains records
Both "Where..." contain records in debug (after clicking on Enumerate)
now the method:
public string genericMethod(<IQueryable>BaseClass _myClass)
{
foreach (BaseClass c in _myClass) // <-------class is empty - no records
{
// do something usefull...
}
return someResult
}
But no records are contained, when inside the method.
Is it possible, what I am trying to do...?
Does it make sense?
There are no design-time or compile-time or runtime errors, but the passed object contains no records when passed to the method, but it contained records in the calling statement.
What did I do wrong?
Is there a better approach? -
I need this Method, for manipulation of more than two (maybe ten) derived classes, and therefor I want it "generic".
Thank you!
When faced with something like this, I like to simplify my code.
I would try removing the _dA.Where(a => a.Name.StartsWith("a name")) and _dB.Where(a => a.Id==5) from the method call and put them into variables first (and then pass the variable into the method).
This will allow you to better inspect your code and perhaps shed light on the problem.
add .ToList() to materialize the query before you pass it to the method:
genericMethod(_dA.Where(a => a.Name.StartsWith("a name"))).ToList());
Otherwise you're not really passing the result of the query, you're just passing a query that needs to be evaluated first. ToList() will evaluate it for you. When you look in the debugger watch, it's basically evaluating it for you on the fly, that's why you see rows returned.
After that, change your method to deal with IList instead of IQueryable.
I am not sure the best approach to this problem, be it through reflection, redesigning my classes altogether, or doing something simple.
Basically I have a base class, and I can have any number of subclasses which inherit from it. Let's call the base class Shape and the subclasses CircleShape, RectangleShape, etc.
The base class is never itself instantiated, only the subclasses. Some are never instatiated, some are instantiated many times throughout the life of the program.
Sometimes I need information specific to a subclass before I instantiate it. Right now I use an enum to differentiate all subclass types. And I instantiate each subclass based on the enum in a switch statement, like this:
switch (shapeType)
{
case CircleShape:
shape = new CircleShape();
case SquareShape:
shape = new RectangleShape();
}
But say instead of having to use this kind of hardcoded switch statement, I wanted to enumerate through all the subclasses. Is there a way to automatically retrieve a list of subclasses and access their STATIC members for info about them (before instantiating them)? Or is it easier to manually instantiate each class once and add them to an array so an I enumerate through them (but not tie those instances to any actual data).
Or should I do something completely different?
You can use attributes to define metadata on your classes and then use reflection to read this metadata at runtime to decide what you want to do with this class without having to instantiate it.
Here's some information on using attributes (you can create your own custom attributes too) using attributes in C#
Here's a quick sample of what this would look like:
Class Defenition:
// ********* assign the attributes to the class ********
[BugFixAttribute(121,"Jesse Liberty","01/03/05")]
[BugFixAttribute(107,"Jesse Liberty","01/04/05", Comment="Fixed off by one errors")]
public class MyMath
{
...
Using Reflection to read the attributes:
// get the member information and use it to retrieve the custom attributes
System.Reflection.MemberInfo inf = typeof(MyMath);
object[] attributes;
attributes = inf.GetCustomAttributes(typeof(BugFixAttribute), false);
// iterate through the attributes, retrieving the properties
foreach(Object attribute in attributes)
{
BugFixAttribute bfa = (BugFixAttribute) attribute;
Console.WriteLine("\nBugID: {0}", bfa.BugID);
Console.WriteLine("Programmer: {0}", bfa.Programmer);
Console.WriteLine("Date: {0}", bfa.Date);
Console.WriteLine("Comment: {0}", bfa.Comment);
}
NOTE: Be careful with using reflection too heavily on large numbers of iterations of large number of objects though, since it comes with a significant performance cost.
You could use reflection to enumerate all your classes, but this is not a very efficient way to do things since it is kind of slow.
If they are all in the same assembly you could do something like:
class Shape
{
/* ... */
}
class CircleShape : Shape
{
public static string Name
{
get
{
return "Circle";
}
}
}
class RectangleShape : Shape
{
public static string Name
{
get
{
return "Rectangle";
}
}
}
class Program
{
static void Main(string[] args)
{
var subclasses = Assembly.GetExecutingAssembly().GetTypes().Where(type => type.IsSubclassOf(typeof(Shape)));
foreach (var subclass in subclasses)
{
var nameProperty = subclass.GetProperty("Name", BindingFlags.Public | BindingFlags.Static);
if (nameProperty != null)
{
Console.WriteLine("Type {0} has name {1}.", subclass.Name, nameProperty.GetValue(null, null));
}
}
}
}
Of course you could also use attributes instead of static members which would probably preferable if you want to decorate the classes with information that you wanted to look up at runtime. There are many examples of how attributes work around the internet.
Take this example:
interface IEntity {
string Name { get; set; }
}
class Product : IEntity {
public string Name { get; set; }
public int Count { get; set; } // added member
}
class Client {
void Process() {
var product = new Product();
int count = product.Count; // this is valid
}
}
In the example above, what is the type of product? Is it IEntity or Product? It appears that product is of type concrete implementation (Product). If that is the case, shouldn't var be used only in special circumstances. But I see that tools like resharper recommend using var by default. Shouldn't one program to an interface?
You are not actually "programming to interfaces" if you are still instantiating the concrete class within the method, as the dependency to the concrete Product class still remains. In order to properly program-to-interfaces you must remove the new instantiation, for example by using a factory or IoC.
What if you had a Product like ...
class Product : IFirst, ISecond, IThrid
The only rational thing the complier can do is what it does. I don't limit my use of var, I use it everywhere. I think it makes code far more readable. In this case, I agree with ReSharper across the board.
If you want Product to be of type IEntity, try this:
var product = new Product() as IEntity;
That said, yes you should program to an interface, but in your case you're instantiating the concrete type directly. If you've already created a dependency to the concrete type, just use the concrete type. If not, use a factory or injection to get an instance of the interface. var will work with those rather well. For example:
public class MyExtremelySimpleFactoryExampleClass
{
public IEntity Instantiate()
{
return new Product();
}
}
// elsewhere in your code...
var item = myFactory.Instantiate(); // item is of type IEntity
Finally, no, I don't think var should be used only in "special circumstances". I find it quite useful and use it almost always.
var product = new Product() is of type Product. You could program to the interface if you weren't using members outside that interface (Product.Count isn't on the IEntity interface).
Added:
Also, in VS2008, you can hover over the var keyword in the declaration to see the implied type. This hover/tooltip message also works on the variable name after the declaration line. (from C# In Depth, page 211)
The type that is inferred is the actual type, not any interface or base class that it may implement/inherit.
Consider this:
var answer = "42";
If it would infer an interface rather than the type, the variable type would be something like IComparable instead of string.
The usage of the var keyword relies on it inferring the actual type, or it would not make sense to use it for anything other than anonymous types. As long as the type is obvious you can use it to make the code more readable, but if the type is not completely obvious, you should avoid using it. (My example above is in the gray area, as it does not actually contain the string type name.)
If you use var in this instance, it will be of type Product. I don't like using var by default, as it can make reading code a little confusing at times.
I prefer using var mostly in LINQ queries, but try not to overuse it in other places (like your example). For people using an IDE with intellisense it is fine, but if you are ever reading the code with Notepad (or Notepad++, etc.), you will have a harder time figuring out the type without a little research.