Implement a dictionary of classes for a pseudo class factory - c#

I´m trying to buld a class factory like that:
public class Toyota() {};
public class Bmw() {};
public class Mercedes() {};
public class BrandFactory
{
private Dictionary<string, object> _Brands = new Dictionary<string, object> {
{"Toyota", Toyota},
{"Bmw", Bmw},
{"Mercedes", Mercedes}
}
public object GetBrand(string brandName)
{
return = BusinessManagers[brandName].Invoke;
}
}
This is the idea, but it´s not working - I can´t even compile the above code as the Dictionary cannot associate an 'object' with the function. I tried Func<> as well, but in that case it requires a previous type.
So, here are my questions:
Is that a correct way to implement this 'pseudo factory' ? The code came from the example at example code
If so, what needs to be fixed in the above code ?
The reason I´m asking that is because I need to create a new object based on a string that is received from a cliente application using Ajax. Like:
AjaxCall -> String Containing Object Name -> Object Inoke -> Method Call -> Send result back to client
The Method Call is a standard for all implementation of Brand.
Please can someone help me with that ?
Thanks.

You have a several options here. If you end up using a Dictionary, I recommend making it case-insensitive and taking care to avoid KeyNotFoundExceptions.
public class CaseInsensitiveStringComparer : IComparer<string>
{
public int Compare(string x, string y)
{
return string.Compare(x, y, ignoreCase: true);
}
}
The first option is to use Dictionary<string, Func<object>>.
private IDictionary<string, Func<object>> _Brands
= new Dictionary<string, Func<object>> (new CaseInsensitiveStringComparer())
{
{"Toyota", () => new Toyota() },
{"BMW", () => new Bmw() },
{"Mercedes", () => Mercedes() }
};
public object GetBrand(string brandName)
{
Func<object> func;
return _Brands.TryGetValue(brandName, out func)
? func() // invoking the delegate creates the instance of the brand object
: null; // brandName was not in the dictionary
}
Second option is to use Activator. You can use a Dictionary<string,Type>, but it may not be necessary if your type name matches the string (see notes below).
public object GetBrand(string brandName)
{
Type type;
return _Brands.TryGetValue(brandName, out type)
? Activator.CreateInstance(type) // activator invokes a parameterless constructor
: null; // brandName was not in the dictionary
}
// vs.
return Activator.CreateInstance(null, brandName).Unwrap();
// Case sensitivity would be an issue here.
// Security could be an issue here.
// Creating objects based directly off of user input means any class
// from any referenced assembly could be created if a hacker can learn
// out the namespaces and class names.
Third option is to use an IoC container to do the resolution. This gives you some flexibility with lifetime management.
The second approach currently assumes a parameterless constructor, wherease the first and third would allow for disparate constructor signatures.
In all cases, the result is simply object, which gives this approach limited utility. If all of these "brand" classes could share a common interface, then you could use IBrand or whatever in your Dictionary and as the return type.
I'm checking for bad data (values not in the Dictionary) and returning null; you could choose to throw an Exception if that makes more sense for your use case.*

You do not need a Dictionary at all:
public class DynamicFactory<T>
{
public static T Create(string className)
{
Type t = typeof(T);
return (T)Activator.CreateInstance(
t.Assembly.FullName,
t.Namespace + "." + className
).Unwrap();
}
}
namespace Brands
{
public class CarBrand { }
// The brands should be in the same namespace and assembly with CarBrand
// and should inherit from CarBrand
public class Toyota : CarBrand { };
public class Bmw : CarBrand { };
public class Mercedes : CarBrand { };
public class Titanic { } // this one is not CarBrand
class BrandFactory: DynamicFactory<CarBrand> { }
// Below are unit tests using NUnit
namespace BrandFactorySpecification
{
static class Create
{
[TestCase("Toyota", Result = typeof(Toyota))]
[TestCase("Bmw", Result = typeof(Bmw))]
[TestCase("Mercedes", Result = typeof(Mercedes))]
[TestCase("Titanic", ExpectedException = typeof(InvalidCastException))]
[TestCase("unknown", ExpectedException = typeof(TypeLoadException))]
[TestCase("String", ExpectedException = typeof(TypeLoadException))]
[TestCase("System.String", ExpectedException = typeof(TypeLoadException))]
[TestCase("ACarBrandFromAnotherNamespace",
ExpectedException = typeof(TypeLoadException))]
[TestCase("AnotherNamespace.ACarBrandFromAnotherNamespace",
ExpectedException = typeof(TypeLoadException))]
//
public static Type ShouldReturnCorrectType(string brandName)
{
return BrandFactory.Create(brandName).GetType();
}
[Test]
public static void ForTitanic()
{
DynamicFactory<Titanic>.Create("Titanic")
.ShouldBeType(typeof(Titanic));
}
}
namespace AnotherNamespace
{
public class ACarBrandFromAnotherNamespace : CarBrand { };
}
}
}
Update: the code was improved in the following ways:
The security problem, mentioned in the comments was fixed
flexibility improved
A new generic class DynamicFactory<T> now can be reused elsewhere
Brands can be located in other namespace and assembly then BrandFactory
Unit tests were added to serve as examples of usage and specification (using NUnit required for them)

That's not at all how a factory works. First of all you need a superclass that can be the parent of your car models:
public class CarModel() {};
public class Toyota() : CarModel {};
public class Bmw() : CarModel {};
public class Mercedes() : CarModel {};
Now you can create a factory that returns the correct model:
public class BrandFactory
{
public T GetBrand<T>() where T : CarModel
{
return new T();
}
}
Now when you want to create a object its is simple:
var factory = new BrandFactory();
var bmw = factory.GetBrand<Bmw>();

Related

how to know all generics type values in c#?

i have simple class like below :
public class HelathCheck<T>
{
public static Dictionary<string, CircuitBreakerPolicy<T>> pollyPolicies = new Dictionary<string, CircuitBreakerPolicy<T>>();
}
i am adding value like below to this Policies dynamically.
HelathCheck<ClassA>.pollyPolicies.Add("SportsAPI1", Policy1);
HelathCheck<ClassB>.pollyPolicies.Add("SportsAPI2", Policy2);
HelathCheck<ClassC>.pollyPolicies.Add("SportsAPI3", Policy3);
HelathCheck<ClassD>.pollyPolicies.Add("SportsAPI4", Policy4);
i am storing some CircuitBreakerPolicy in Dictionary object so i can use get value later.
now i want to know all value which is stored into SoapPollyPolicies from one method
something like this, basically how do i know values store in all class?
can you please give me some hints? Thanks ( is this is right question?, not sure )
// here i do not want to pass classA, classB..etc, just one line and all values, i wanted to get it.
foreach (var item in HelathCheck<??>.SoapPollyPolicies)
{
response.Add(item.Key, item.Value);
}
may be something like this but only class ==>
https://expertcodeblog.wordpress.com/2018/02/07/c-get-all-types-that-implement-an-interface/
the closest i can reach to this is :
var type = typeof(HelathCheck<>);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
foreach (var item1 in types)
{
//do stuff
var prop = item1.GetField("pollyPolicies "); // FaultResponse is one of object from SOAP resposne.
//var value= prop.GetValue("pollyPolicies");
}
You do not need generics here. You say they are a common base class so do
public class HelathCheck
{
public static Dictionary<string, BreakerBase> pollyPolicies = new Dictionary<string, BreakerBase>();
}
and put all the obects in that one dictioanry
The most accurate way of doing this would be to create an interface for your test classes, and have each test class implement that interface.
public interface ITestClass { }
public class TestClassA : ITestClass
{
}
public class TestClassB : ITestClass
{
}
In your HealthCheck class, add a type constraint:
public class HealthCheck<T> where T : ITestClass
{
public static Dictionary<string, T> Policies { get; set; }
}
Now, you can then enumerate over the added items using ITestClass as your type parameter like so:
public class Consumer
{
public Consumer()
{
HealthCheck<TestClassA>.Policies.Add("API1", new TestClassA());
HealthCheck<TestClassB>.Policies.Add("API2", new TestClassB());
foreach (var policy in HealthCheck<ITestClass>.Policies)
{
Console.WriteLine(policy.Key);
Console.WriteLine(policy.Value);
}
}
}

Returning different types from the same method

I have two objects that are similar but not quite the same:
public class ObjectA
{
public string PropertyA { get; set; }
}
public class ObjectB
{
public string PropertyA { get; set; }
public string PropertyB { get; set; }
}
In both objects PropertyA is used for database lookup via a stored procedure, however, the stored procedure used differs between the objects. Assuming the stored procedure returns successfully, the response is used to create the relevant object.
Currently I have two methods that perform the same logic of calling the relevant stored procedure and then creating the object:
public ObjectA QueryObjectA(string propertyA)
{
// shared code
var result = CallToStoredProcedureA(...);
var obj = new ObjectA
{
// use result here
};
return obj;
}
public ObjectB QueryObjectB(string propertyA)
{
// shared code
var result = CallToStoredProcedureB(...);
var obj = new ObjectB
{
// use result here
};
return obj;
}
This works, however, I am maintaining some shared code in multiple places and if I were to add another object in the future I would potentially have a third method (QueryObjectC).
Can this, or should this, be improved through the use of generics and if so what might that look like? Perhaps something along the lines of the following?
public T QueryObject<T>(string propertyA) where T : new()
{
// shared code
// get type of T
// switch statement that calls the relevant stored procedure and creates the object
// return object
}
So either way, you're probably going to want to create a common interface between A and B. We'll call it IBase
Now the simplest solution would be to try move this procedure to inside IBase, and let polymorphism do the hard work for you
public T QueryObject<T>() where T: IBase, new()
{
var obj = new T();
var result = obj.DoProcedure(...);
obj.AssignResults(result); // could be a part of DoProcedure
return obj;
}
with
interface IBase
{
ResultType DoProcedure(...);
}
and each A or B would impliment the correct call (possibly using a visitor pattern if needed)
If however this procedure really isn't the responsibility of A or B (from the looks of it it could be, but if it's not) then you can upgrade to the slightly more heavy duty solution of a Factory of some kind.
You'll want a similar interface as before, but this one you can leave empty
interface IBase
{ }
And a IProcedureExecutor interface (name can be improved
interface IProcedureExecutor
{
ResultType DoProcedure(...);
}
The implimemtors would each impliment the function, ATypeProcExecutor : IProcedureExexutor, BTypeProcExecutor : IProcedureExexutor
Then a Factory
class ProcedureExecutorFactory
{
private static Dictionary<Type, IProcedureExecutor> executors = new
{
{typeof(A), new ATypeProcExecutor},
{typeof(B), new BTypePrpcExecutor}
};
public static IProcedureExecutor GetExecutor(Type t)
{
return executors[t];
}
}
Then your QueryObject function would be
public T QueryObject<T>() where T: IBase, new()
{
var executor = ProcedureExecutorFactory.GetExecutor(typeof(T));
var result = executor.DoProcedure(...);
var obj = new T();
obj.AssignResults(result);// could be part of constructor
return obj;
}
The second is probably more SOLID but might well be overkill for your problem.
You mentioned a switch statement in your question's sudocode, this is a bad idea. A generic function that switches based on the type of T is really loosing all the flexibility benifits gained by using a generic at all.
Wanting to do something different based on the type of an object is really the heart of OOP, so making good use of polymorphism is really the way to go here.
(on my phone so code untested)
By using a common abstract base class ObjectBase having the property PropertyA you could write
public T QueryObject<T>(string propertyA) where T : ObjectBase, new()
{
var result = typeof(T).Name switch {
nameof(ObjectA) => CallToStoredProcedureA(...),
nameof(ObjectB) => CallToStoredProcedureB(...),
_ => throw new NotImplementedException()
};
var obj = new T {
PropertyA = result
};
return obj;
}
If the initialization is different for the different object types, then you could consider adding a static factory method to these types.
Objects with factory methods:
public class ObjectA : ObjectBase
{
public static ObjectA Create(string storedProcResult) =>
new() { PropertyA = storedProcResult };
}
public class ObjectB : ObjectBase
{
public string PropertyB { get; set; }
public static ObjectB Create(string storedProcResult) =>
new() {
PropertyA = storedProcResult.Substring(0, 3),
PropertyB = storedProcResult.Substring(3)
};
}
Generic method using the factory methods:
public T QueryObject<T>(string propertyA) where T : ObjectBase, new()
{
ObjectBase obj = typeof(T).Name switch {
nameof(ObjectA) => ObjectA.Create(CallToStoredProcedureA(...)),
nameof(ObjectB) => ObjectB.Create(CallToStoredProcedureB(...)),
_ => throw new NotImplementedException()
};
return (T)obj;
}

Why is it impossible to cast to a derived type [duplicate]

Is it possible to assign a base class object to a derived class reference with an explicit typecast in C#?.
I have tried it and it creates a run-time error.
No. A reference to a derived class must actually refer to an instance of the derived class (or null). Otherwise how would you expect it to behave?
For example:
object o = new object();
string s = (string) o;
int i = s.Length; // What can this sensibly do?
If you want to be able to convert an instance of the base type to the derived type, I suggest you write a method to create an appropriate derived type instance. Or look at your inheritance tree again and try to redesign so that you don't need to do this in the first place.
No, that's not possible since assigning it to a derived class reference would be like saying "Base class is a fully capable substitute for derived class, it can do everything the derived class can do", which is not true since derived classes in general offer more functionality than their base class (at least, that's the idea behind inheritance).
You could write a constructor in the derived class taking a base class object as parameter, copying the values.
Something like this:
public class Base {
public int Data;
public void DoStuff() {
// Do stuff with data
}
}
public class Derived : Base {
public int OtherData;
public Derived(Base b) {
this.Data = b.Data;
OtherData = 0; // default value
}
public void DoOtherStuff() {
// Do some other stuff
}
}
In that case you would copy the base object and get a fully functional derived class object with default values for derived members. This way you can also avoid the problem pointed out by Jon Skeet:
Base b = new Base();//base class
Derived d = new Derived();//derived class
b.DoStuff(); // OK
d.DoStuff(); // Also OK
b.DoOtherStuff(); // Won't work!
d.DoOtherStuff(); // OK
d = new Derived(b); // Copy construct a Derived with values of b
d.DoOtherStuff(); // Now works!
Solution with JsonConvert (instead of typecast)
Today i faced the same issue and i found a simple and quick solution to the problem using JsonConvert.
var base = new BaseClass();
var json = JsonConvert.SerializeObject(base);
DerivedClass derived = JsonConvert.DeserializeObject<DerivedClass>(json);
I had this problem and solved it by adding a method that takes a type parameter and converts the current object into that type.
public TA As<TA>() where TA : Base
{
var type = typeof (TA);
var instance = Activator.CreateInstance(type);
PropertyInfo[] properties = type.GetProperties();
foreach (var property in properties)
{
property.SetValue(instance, property.GetValue(this, null), null);
}
return (TA)instance;
}
That means that you can use it in you code like this:
var base = new Base();
base.Data = 1;
var derived = base.As<Derived>();
Console.Write(derived.Data); // Would output 1
As many others have answered, No.
I use the following code on those unfortunate occasions when I need to use a base type as a derived type. Yes it is a violation of the Liskov Substitution Principle (LSP) and yes most of the time we favor composition over inheritance. Props to Markus Knappen Johansson whose original answer this is based upon.
This code in the base class:
public T As<T>()
{
var type = typeof(T);
var instance = Activator.CreateInstance(type);
if (type.BaseType != null)
{
var properties = type.BaseType.GetProperties();
foreach (var property in properties)
if (property.CanWrite)
property.SetValue(instance, property.GetValue(this, null), null);
}
return (T) instance;
}
Allows:
derivedObject = baseObect.As<derivedType>()
Since it uses reflection, it is "expensive". Use accordingly.
No it is not possible, hence your runtime error.
But you can assign an instance of a derived class to a variable of base class type.
As everyone here said, that's not possible directly.
The method I prefer and is rather clean, is to use an Object Mapper like AutoMapper.
It will do the task of copying properties from one instance to another (Not necessarily the same type) automatically.
In c# 9.0 you can try to use records for this. They have default copy constructor that copy all fields - no need to use reflection / constructor with all fields.
public record BaseR
{
public string Prop1 { get; set; }
}
public record DerivedR : BaseR
{
public DerivedR(BaseR baseR) : base(baseR) { }
public string Prop2 { get; set; }
}
var baseR = new BaseR { Prop1 = "base prob" };
var derivedR = new DerivedR(baseR) { Prop2 = "new prop" };
Not in the Traditional Sense... Convert to Json, then to your object, and boom, done! Jesse above had the answer posted first, but didn't use these extension methods which make the process so much easier. Create a couple of extension methods:
public static string ConvertToJson<T>(this T obj)
{
return JsonConvert.SerializeObject(obj);
}
public static T ConvertToObject<T>(this string json)
{
if (string.IsNullOrEmpty(json))
{
return Activator.CreateInstance<T>();
}
return JsonConvert.DeserializeObject<T>(json);
}
Put them in your toolbox forever, then you can always do this:
var derivedClass = baseClass.ConvertToJson().ConvertToObject<derivedClass>();
Ah, the power of JSON.
There are a couple of gotchas with this approach: We really are creating a new object, not casting, which may or may not matter. Private fields will not be transferred, constructors with parameters won't be called, etc. It is possible that some child json won't be assigned. Streams are not innately handled by JsonConvert. However, if our class doesn't rely on private fields and constructors, this is a very effective method of moving data from class to class without mapping and calling constructors, which is the main reason why we want to cast in the first place.
Expanding on #ybo's answer - it isn't possible because the instance you have of the base class isn't actually an instance of the derived class. It only knows about the members of the base class, and doesn't know anything about those of the derived class.
The reason that you can cast an instance of the derived class to an instance of the base class is because the derived class actually already is an instance of the base class, since it has those members already. The opposite cannot be said.
You can cast a variable that is typed as the base-class to the type of a derived class; however, by necessity this will do a runtime check, to see if the actual object involved is of the correct type.
Once created, the type of an object cannot be changed (not least, it might not be the same size). You can, however, convert an instance, creating a new instance of the second type - but you need to write the conversion code manually.
You have to use an object cloner/copier that will assign all the properties one by one.
Doing this by hand is inefficient and not future-proof. But serializing & deserializing to JSON and back is not the best solution, it is slow and very memory inefficient.
However, using AutoMapper is fast. PropMapper is even faster.
PS. Disclosure: I am a contributor at PropMapper open source project.
No, it is not possible.
Consider a scenario where an ACBus is a derived class of base class Bus. ACBus has features like TurnOnAC and TurnOffAC which operate on a field named ACState. TurnOnAC sets ACState to on and TurnOffAC sets ACState to off. If you try to use TurnOnAC and TurnOffAC features on Bus, it makes no sense.
class Program
{
static void Main(string[] args)
{
a a1 = new b();
a1.print();
}
}
class a
{
public a()
{
Console.WriteLine("base class object initiated");
}
public void print()
{
Console.WriteLine("base");
}
}
class b:a
{
public b()
{
Console.WriteLine("child class object");
}
public void print1()
{
Console.WriteLine("derived");
}
}
}
when we create a child class object,the base class object is auto initiated so base class reference variable can point to child class object.
but not vice versa because a child class reference variable can not point to base class object because no child class object is created.
and also notice that base class reference variable can only call base class member.
There actually IS a way to do this. Think about how you might use Newtonsoft JSON to deserialize an object from json. It will (or at least can) ignore missing elements and populate all the elements that it does know about.
So here's how I did it. A small code sample will follow my explanation.
Create an instance of your object from the base class and populate it accordingly.
Using the "jsonconvert" class of Newtonsoft json, serialize that object into a json string.
Now create your sub class object by deserializing with the json string created in step 2. This will create an instance of your sub class with all the properties of the base class.
This works like a charm! So.. when is this useful? Some people asked when this would make sense and suggested changing the OP's schema to accommodate the fact that you can't natively do this with class inheritance (in .Net).
In my case, I have a settings class that contains all the "base" settings for a service. Specific services have more options and those come from a different DB table, so those classes inherit the base class. They all have a different set of options. So when retrieving the data for a service, it's much easier to FIRST populate the values using an instance of the base object. One method to do this with a single DB query. Right after that, I create the sub class object using the method outlined above. I then make a second query and populate all the dynamic values on the sub class object.
The final output is a derived class with all the options set. Repeating this for additional new sub classes takes just a few lines of code. It's simple, and it uses a very tried and tested package (Newtonsoft) to make the magic work.
This example code is vb.Net, but you can easily convert to c#.
' First, create the base settings object.
Dim basePMSettngs As gtmaPayMethodSettings = gtmaPayments.getBasePayMethodSetting(payTypeId, account_id)
Dim basePMSettingsJson As String = JsonConvert.SerializeObject(basePMSettngs, Formatting.Indented)
' Create a pmSettings object of this specific type of payment and inherit from the base class object
Dim pmSettings As gtmaPayMethodAimACHSettings = JsonConvert.DeserializeObject(Of gtmaPayMethodAimACHSettings)(basePMSettingsJson)
You can use an Extention:
public static void CopyOnlyEqualProperties<T>(this T objDest, object objSource) where T : class
{
foreach (PropertyInfo propInfo in typeof(T).GetProperties())
if (objSource.GetType().GetProperties().Any(z => z.Name == propInfo.Name && z.GetType() == propInfo.GetType()))
propInfo.SetValue(objDest, objSource.GetType().GetProperties().First(z => z.Name == propInfo.Name && z.GetType() == propInfo.GetType()).GetValue(objSource));
}
In Code:
public class BaseClass
{
public string test{ get; set;}
}
public Derived : BaseClass
{
//Some properies
}
public void CopyProps()
{
BaseClass baseCl =new BaseClass();
baseCl.test="Hello";
Derived drv=new Derived();
drv.CopyOnlyEqualProperties(baseCl);
//Should return Hello to the console now in derived class.
Console.WriteLine(drv.test);
}
Might not be relevent, but I was able to run code on a derived object given its base. It's definitely more hacky than I'd like, but it works:
public static T Cast<T>(object obj)
{
return (T)obj;
}
...
//Invoke parent object's json function
MethodInfo castMethod = this.GetType().GetMethod("Cast").MakeGenericMethod(baseObj.GetType());
object castedObject = castMethod.Invoke(null, new object[] { baseObj });
MethodInfo jsonMethod = baseObj.GetType ().GetMethod ("ToJSON");
return (string)jsonMethod.Invoke (castedObject,null);
You can do this using generic.
public class BaseClass
{
public int A { get; set; }
public int B { get; set; }
private T ConvertTo<T>() where T : BaseClass, new()
{
return new T
{
A = A,
B = B
}
}
public DerivedClass1 ConvertToDerivedClass1()
{
return ConvertTo<DerivedClass1>();
}
public DerivedClass2 ConvertToDerivedClass2()
{
return ConvertTo<DerivedClass2>();
}
}
public class DerivedClass1 : BaseClass
{
public int C { get; set; }
}
public class DerivedClass2 : BaseClass
{
public int D { get; set; }
}
You get three benefits using this approach.
You are not duplicating the code
You are not using reflection (which is slow)
All of your conversions are in one place
I know this is old but I've used this successfully for quite a while.
private void PopulateDerivedFromBase<TB,TD>(TB baseclass,TD derivedclass)
{
//get our baseclass properties
var bprops = baseclass.GetType().GetProperties();
foreach (var bprop in bprops)
{
//get the corresponding property in the derived class
var dprop = derivedclass.GetType().GetProperty(bprop.Name);
//if the derived property exists and it's writable, set the value
if (dprop != null && dprop.CanWrite)
dprop.SetValue(derivedclass,bprop.GetValue(baseclass, null),null);
}
}
I combined some portions of the previous answers (thanks to those authors) and put together a simple static class with two methods that we're using.
Yes, it's simple, no it doesn't cover all scenarios, yes it could be expanded and made better, no it's not perfect, yes it could possibly be made more efficient, no it's not the greatest thing since sliced bread, yes there are full-on robust nuget package object mappers out there that are way better for heavy use, etc etc, yada yada - but it works for our basic needs though :)
And of course it will try to map values from any object to any object, derived or not (only the public properties that are named the same of course - ignores the rest).
USAGE:
SesameStreetCharacter puppet = new SesameStreetCharacter() { Name = "Elmo", Age = 5 };
// creates new object of type "RealPerson" and assigns any matching property
// values from the puppet object
// (this method requires that "RealPerson" have a parameterless constructor )
RealPerson person = ObjectMapper.MapToNewObject<RealPerson>(puppet);
// OR
// create the person object on our own
// (so RealPerson can have any constructor type that it wants)
SesameStreetCharacter puppet = new SesameStreetCharacter() { Name = "Elmo", Age = 5 };
RealPerson person = new RealPerson("tall") {Name = "Steve"};
// maps and overwrites any matching property values from
// the puppet object to the person object so now our person's age will get set to 5 and
// the name "Steve" will get overwritten with "Elmo" in this example
ObjectMapper.MapToExistingObject(puppet, person);
STATIC UTILITY CLASS:
public static class ObjectMapper
{
// the target object is created on the fly and the target type
// must have a parameterless constructor (either compiler-generated or explicit)
public static Ttarget MapToNewObject<Ttarget>(object sourceobject) where Ttarget : new()
{
// create an instance of the target class
Ttarget targetobject = (Ttarget)Activator.CreateInstance(typeof(Ttarget));
// map the source properties to the target object
MapToExistingObject(sourceobject, targetobject);
return targetobject;
}
// the target object is created beforehand and passed in
public static void MapToExistingObject(object sourceobject, object targetobject)
{
// get the list of properties available in source class
var sourceproperties = sourceobject.GetType().GetProperties().ToList();
// loop through source object properties
sourceproperties.ForEach(sourceproperty => {
var targetProp = targetobject.GetType().GetProperty(sourceproperty.Name);
// check whether that property is present in target class and is writeable
if (targetProp != null && targetProp.CanWrite)
{
// if present get the value and map it
var value = sourceobject.GetType().GetProperty(sourceproperty.Name).GetValue(sourceobject, null);
targetobject.GetType().GetProperty(sourceproperty.Name).SetValue(targetobject, value, null);
}
});
}
}
You can use a copy constructor that immediately invokes the instance constructor, or if your instance constructor does more than assignments have the copy constructor assign the incoming values to the instance.
class Person
{
// Copy constructor
public Person(Person previousPerson)
{
Name = previousPerson.Name;
Age = previousPerson.Age;
}
// Copy constructor calls the instance constructor.
public Person(Person previousPerson)
: this(previousPerson.Name, previousPerson.Age)
{
}
// Instance constructor.
public Person(string name, int age)
{
Name = name;
Age = age;
}
public int Age { get; set; }
public string Name { get; set; }
}
Referenced the Microsoft C# Documentation under Constructor for this example having had this issue in the past.
With regarding #MarkusKnappenJohansson answer and below comments we can change his code extending extension function :) so it may update an existing deriving class instance via this code :
public static TDerived As<TDerived>(this Base baseInstance, TDerived updateDerivedInstance = null) where TDerived : Base, new()
{
Type baseType = typeof(Base);
Type derivedType = typeof(TDerived);
PropertyInfo[] properties = baseType.GetProperties();
object instanceDerived = null;
if (updateDerivedInstance == null)
{
instanceDerived = Activator.CreateInstance(derivedType);
}
else
{
instanceDerived = (object)(updateDerivedInstance);
}
foreach (PropertyInfo property in properties)
{
if (property.CanWrite)
{
property.SetValue(instanceDerived, property.GetValue(baseInstance, null), null);
}
}
return (TDerived)instanceDerived;
}
Usage for getting new derived Instance is var base = new Base(); base.Data = 1; var derived = base.As<Derived>(); Console.Write(derived.Data); // Would output 1
Usage for updating existing derived Instance is var derived = new Derived(); var base = new Base(); base.Data = 1; var derivedUpdated = base.As<Derived>(derived); Console.Write(derivedUpdated.Data); // Would output 1
Another solution is to add extension method like so:
public static void CopyProperties(this object destinationObject, object sourceObject, bool overwriteAll = true)
{
try
{
if (sourceObject != null)
{
PropertyInfo[] sourceProps = sourceObject.GetType().GetProperties();
List<string> sourcePropNames = sourceProps.Select(p => p.Name).ToList();
foreach (PropertyInfo pi in destinationObject.GetType().GetProperties())
{
if (sourcePropNames.Contains(pi.Name))
{
PropertyInfo sourceProp = sourceProps.First(srcProp => srcProp.Name == pi.Name);
if (sourceProp.PropertyType == pi.PropertyType)
if (overwriteAll || pi.GetValue(destinationObject, null) == null)
{
pi.SetValue(destinationObject, sourceProp.GetValue(sourceObject, null), null);
}
}
}
}
}
catch (ApplicationException ex)
{
throw;
}
}
then have a constructor in each derived class that accepts base class:
public class DerivedClass: BaseClass
{
public DerivedClass(BaseClass baseModel)
{
this.CopyProperties(baseModel);
}
}
It will also optionally overwrite destination properties if already set (not null) or not.
Is it possible to assign a base class object to a derived class reference with an explicit typecast in C#?.
Not only explicit, but also implicit conversions are possible.
C# language doesn't permit such conversion operators, but you can still write them using pure C# and they work. Note that the class which defines the implicit conversion operator (Derived) and the class which uses the operator (Program) must be defined in separate assemblies (e.g. the Derived class is in a library.dll which is referenced by program.exe containing the Program class).
//In library.dll:
public class Base { }
public class Derived {
[System.Runtime.CompilerServices.SpecialName]
public static Derived op_Implicit(Base a) {
return new Derived(a); //Write some Base -> Derived conversion code here
}
[System.Runtime.CompilerServices.SpecialName]
public static Derived op_Explicit(Base a) {
return new Derived(a); //Write some Base -> Derived conversion code here
}
}
//In program.exe:
class Program {
static void Main(string[] args) {
Derived z = new Base(); //Visual Studio can show squiggles here, but it compiles just fine.
}
}
When you reference the library using the Project Reference in Visual Studio, VS shows squiggles when you use the implicit conversion, but it compiles just fine. If you just reference the library.dll, there are no squiggles.
How about:
public static T As<T>(this object obj)
{
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(obj));
}
Best way to add all base properties to derived item is use reflection in costructor. Try this code, without creating methods or instances.
public Derived(Base item) :base()
{
Type type = item.GetType();
System.Reflection.PropertyInfo[] properties = type.GetProperties();
foreach (var property in properties)
{
try
{
property.SetValue(this, property.GetValue(item, null), null);
}
catch (Exception) { }
}
}
I disagree that it is not possible. You can do it like this:
public class Auto
{
public string Make {get; set;}
public string Model {get; set;}
}
public class Sedan : Auto
{
public int NumberOfDoors {get; set;}
}
public static T ConvertAuto<T>(Sedan sedan) where T : class
{
object auto = sedan;
return (T)loc;
}
Usage:
var sedan = new Sedan();
sedan.NumberOfDoors = 4;
var auto = ConvertAuto<Auto>(sedan);
This is how I solved this for fields. You can do the same iteration through properties if you want. You may want to do some checks for null etc. but this is the idea.
public static DerivedClass ConvertFromBaseToDerived<BaseClass, DerivedClass>(BaseClass baseClass)
where BaseClass : class, new()
where DerivedClass : class, BaseClass, new()
{
DerivedClass derived = (DerivedClass)Activator.CreateInstance(typeof(DerivedClass));
derived.GetType().GetFields().ToList().ForEach(field =>
{
var base_ = baseClass.GetType().GetField(field.Name).GetValue(baseClass);
field.SetValue(derived, base_);
});
return derived;
}
You can just serialize the base object to JSON and then deserialize it to the derived object.
No, see this question which I asked - Upcasting in .NET using generics
The best way is to make a default constructor on the class, construct and then call an Initialise method

How to dynamically cast a list of based type to derived type

I have a dll with the following hierarchy:
Interface ISchema {}
class Schema:ISchema{}
class TableSchema:Schema{}
class ViewSchema:Schema{}
I have another dll having the following hierarchy:
Interface ISearch {}
class Table:ISearch{}
class View:ISearch{}
The following code is triggering the search operation on Table or View according to user selection:
private void FindNowButton_Click(object sender, EventArgs e)
{
// return Table or View according to user selection. (Property is an internal class helping to retrieve the selected type)
var type = (ObjectsTypeComboBox.SelectedItem as Property).Type;
// Create an instance of table or View as ISearch
var instance = (ISearch)Activator.CreateInstance(type);
// Call to relevant Search (table.Search or View.Search)
// _dataManager help to get the records from Schema hierarchy
// text is the text to search
var result = instance.Search(_dataManager, FindWhatTextBox.Text);
// Show in DataGridView the result
FindResultsDGV.DataSource = result;
}
Each search method returns a List. I need to display different columns on the grid. TableSchema and ViewSchema has different properties, casting as following is doing the job.
FindResultsDGV.DataSource = result.Cast<TableSchema> ; // or result.Cast<ViewSchema>
How can I dynamically get the correct type at this stage?
Any other solution is welcome
UPDATE:
According to #GiladGreen
public interface ISearchSchemaFactory
{
ISearch<ISchema> GetSearch(Type schemaType);
}
public class Factory : ISearchSchemaFactory
{
public ISearch<ISchema> GetSearch(Type schemaType)
{
if (schemaType.Equals(typeof(Table)))
{
return new BL.AdvancedSearch.Table(); // Getting an error here
// Cannot implicitly convert type 'Table' to 'ISearch<ISchema>'. An explicit conversion exists (are you missing a cast?)
}
else if (schemaType.Equals(typeof(View)))
{
// TODO
}
return null; // TODO
}
}
I'd suggest you to change the ISearch as following:
Interface ISearch<out TSchema> where TSchema: ISchema
{
TSchema Search(....);
}
class Table : ISearch<TableSchema>
{
public TableSchema Search(....)
{
//Some searching code
}
}
class View:ISearch<ViewSchema>
{
public ViewSchema Search(....)
{
//Some searching code
}
}
Then what you can also do is have an ISearchSchemaFactory that will give you an instance of the correct ISearch that you need according to the TSchema you give it:
public interface ISearchSchemaFactory
{
ISearch<ISchema> GetSearch(Type schemaType);
}
And the usage: var search = factory.GetSearch(type);
Factoy Implementation Example
public class MappingSearchSchemaFactory : ISearchSchemaFactory
{
public MappingSearchSchemaFactory(Dictionary<Type, ISearch<ISchema>> mapping)
{
Mapping = mapping;
}
ISearch<ISchema> GetSearch(Type schemaType)
{
ISearch<ISchema> result;
if(!Mapping.TryGetValue(schemaType, out result)
{
//Some logging or throwing exception behavior - depends what you want
}
return result;
}
public Dictionary<Type, ISearch<ISchema>> Mapping { get; set; }
}
This specific implementation gets for "someone" the mapping. A possible initialization code can be:
ISearchSchemaFactory factory = new MappingSearchSchemaFactory(
new Dictionary<Type,ISearch<ISchema>>
{ new TableSchema(), new Table() },
{ new ViewSchema(), new view() }
);
But I'd less recommend this. I'd go look at Dependency Injection and IoC Containers to manage the initialization of my objects. I personally use Castle Windsor

Is this method returning a System.Object class an anti-pattern?

I work an an automation team designing tests for electronic components. One thing our framework sorely needs is a single source point for our driver objects for the various pieces of test equipment at a workbench (right now, driver object creation is very wild-west).
Basically, the idea would be there would be one object, constructed based on a configuration file(s), which is the single place all other test code looks to to get the driver objects, based on a name string. I'll call it a "DriverSource" here.
The problem is, these drivers do not present similar interfaces at all. One might be a power supply (with methods like "SetVoltage" and "SetCurrentLimit"), while another might be a digital multimeter (with methods like "ReadVoltage" or "ReadCurrent").
The best solution I've come up with is to have a method with the following declaration:
public object GetDriver(string name);
Then, the test code using my "DriverSource" object would call that method, and then cast the System.Object to the correct driver type (or more accurately, the correct driver interface, like IPowerSupply).
I think casting like that is acceptable because whatever test code is about to use this driver had better know what the interface is. But I was hoping to get some input on whether or not this is an anti-pattern waiting to bite me. Any better pattern for solving this issue would also be greatly appreciated.
A final note: I think this is obvious, but performance is essentially a non-issue for this problem. Fetching the drivers is something will happen less than 100 times in a test run that can last hours.
If you already know the type and you're going to cast to an interface or class anyway, a better approach would be to hand the method call a type parameter.
public T GetDriver<T>(string name);
You can then use a Factory pattern to return you an object of the appropriate type from the method.
public T GetDriver<T>(string name)
{
switch(typeof(T).Name)
{
case "Foo":
// Construct and return a Foo object
case "Bar":
// Construct and return a Bar object
case "Baz":
// Construct and return a Baz object
default:
return default(T);
}
}
Usage:
var driver = GetDriver<Foo>(someString); // Returns a Foo object
If you really want to make this generic, I would use a factory pattern.
Lets start off by identifying the type structure:
public interface IDriver
{
}
public interface IPowerSupply : IDriver
{
void SetVoltage();
void SetCurrent();
}
public interface IMultimeter : IDriver
{
double MeasureVoltage();
}
Which you can add to or remove from as needed. Now we need a way for the factory to auto-discover the correct types and provide the configuration information to it. So lets create a custom attribute:
public class DriverHandlerAttribute : Attribute
{
public Type DriverType { get; set; }
public string ConfigurationName { get; set; }
}
And then we need a place to store configuration data. This type can contain whatever you want, like a dictionary of keys/values that are loaded from configuration files:
public class Configuration
{
public string DriverName { get; set; }
public string OtherSetting { get; set; }
}
Finally we can create a driver. Lets create an IPowerSupply:
[DriverHandler(DriverType = typeof(IPowerSupply), ConfigurationName="BaseSupply")]
public class BasePowerSupply : IPowerSupply
{
public BasePowerSupply(Configuration config) { /* ... */ }
public void SetVoltage() { /* ... */ }
public void SetCurrent() { /* ... */ }
}
The important part is that it is decorated with the attribute and that it has a constructor (although I created the factory so that it can use default constructors too):
public static class DriverFactory
{
public static IDriver Create(Configuration config)
{
Type driverType = GetTypeForDriver(config.DriverName);
if (driverType == null) return null;
if (driverType.GetConstructor(new[] { typeof(Configuration) }) != null)
return Activator.CreateInstance(driverType, config) as IDriver;
else
return Activator.CreateInstance(driverType) as IDriver;
}
public static T Create<T>(Configuration config) where T : IDriver
{
return (T)Create(config);
}
private static Type GetTypeForDriver(string driverName)
{
var type = (from t in Assembly.GetExecutingAssembly().GetTypes()
let attrib = t.GetCustomAttribute<DriverHandlerAttribute>()
where attrib != null && attrib.ConfigurationName == driverName
select t).FirstOrDefault();
return type;
}
}
So to use this, you would read in the configuration data (loaded from XML, read from a service, files, etc). You can then create the driver like:
var driver = DriverFactory.Create(configuration);
Or if you are using the generic method and you know the configuration is for a power supply, you can call:
var driver = DriverFactory.Create<IPowerSupply>(configuration);
And when you run your tests, you can verify that you get the right data back, for example, in your test method:
Assert.IsTrue(driver is IPowerSupply);
Assert.IsTrue(driver is BaseSupply);
Assert.DoesWhatever(((IPowerSupply)driver).SetVoltage());
And so-on and so-forth.
I would go with this code:
public T GetDriver<T>(string name)
{
return ((Func<string, T>)_factories[typeof(T)])(name);
}
The _factories object looks like this:
private Dictionary<Type, Delegate> _factories = new Dictionary<Type, Delegate>()
{
{ typeof(Foo), (Delegate)(Func<string, Foo>)(s => new Foo(s)) },
{ typeof(Bar), (Delegate)(Func<string, Bar>)(s => new Bar()) },
{ typeof(Baz), (Delegate)(Func<string, Baz>)(s => new Baz()) },
};
Basically the _factories dictionary contains all of the code to create each object type based on string parameter passed in. Note that in my example above the Foo class takes s as a constructor parameter.
The dictionary can also then be modified at run-time to suite your needs without needing to recompile code.
I would even go one step further. If you define this factory class:
public class Factory
{
private Dictionary<Type, Delegate> _factories = new Dictionary<Type, Delegate>();
public T Build<T>(string name)
{
return ((Func<string, T>)_factories[typeof(T)])(name);
}
public void Define<T>(Func<string, T> create)
{
_factories.Add(typeof(T), create);
}
}
You can then write this code:
var drivers = new Factory();
drivers.Define(s => new Foo(s));
drivers.Define(s => new Bar());
drivers.Define(s => new Baz());
var driver = drivers.Build<Foo>("foo");
I like that even better. It's strongly-typed and easily customized at run-time.

Categories