merge 2 classes into one class at runtime - c#

Suppose I have Class A with some properties and Attributes, and Class B with the same, how can I merge these 2 class Properties and properties Attributes into 1 class at runtime, or better is how can I add these 2 classes into a a third class as properties of this new class with their Fields, Properties, Methods, etc... at Runtime ?
Using reflection or the News .NET 4.0 Dynamic or expando Object
Edit: Damn I am sorry to all for not being clear, what I want is to create a dynamic ViewModel for MVC, where other classes are in some other assemblies, and I want them to be part of the model with their Datavalidation attributes. and I don't know how many or what exactly these classes are gonna be, so I want to iterate through assemblies and choose them then add them to the main View Model.

You can't change a type at runtime. Expando might be an option, but I am not clear how you want to interact with this object, as you would seem to be limited to reflection, and expando is not a huge friend of reflection.
It might help to clarify your requirement here, but IMO you might do better to consider loading (at runtime) a property-bag based on reflection from the two inputs; something like a Dictionary<string,object> which would let you map named keys to values.
One other thing that might be what you are after here is partial classes, but this is a single type spread over multiple source files:
partial class Foo {
private string bar;
}
partial class Foo {
public string Bar { get {return bar;} set {bar = value;} }
}
A final option here is TypeBuilder, but that is massive overkill in most scenarios.

Assuming you don't have access to the code for either of the classes (otherwise you could just merge the code), you can create a wrapper that aggregates the two classes with the combined interfaces:
public class AandB
{
private ClassA _instanceA = new ClassA();
private ClassB _instanceB = new ClassB();
public bool PropertyA
{
get
{
return _instanceA.PropertyA;
}
set
{
_instanceA.PropertyA = value;
}
}
public bool PropertyB
{
get
{
return _instanceB.PropertyB;
}
set
{
_instanceB.PropertyB = value;
}
}
}

Related

When defining a class that extends a list, how can I refer to the list from its inner methods?

Say that I have a public class MyClass: List<MyObjects>.
I want this class to have an inner method that manipulates the list, say
void ConstructListFromJSON(){
HoweverIshouldrefertomylist = JsonUtility.FromJson<List<MyObjects>("myObjects.json");
}
What should I put in place of the HoweverIshouldrefertomylist ? I've tried this, self and similar but it doesn't work. Surely there's a way to refer to the data strucure in the list?
You cannot reassign this, so clear the list and add whatever you want to add:
var objectsToStore = JsonUtility.FromJson<List<MyObjects>>("myObjects.json");
this.Clear();
this.AddRange(objectsToStore);
But in general, you really don't want to inherit from List<T>. See Why not inherit from List<T>?. Use composition instead:
public class MyClass
{
public List<YourObjects> YourObjects { get; set; }
public void ConstructListFromJSON()
{
YourObjects = JsonUtility.FromJson<List<MyObjects>("myObjects.json");
}
}
To properly generate classes representing your JSON, see Deserializing JSON into an object
To access a base object, just use the base keyword. But, for what you are showing, a different approach makes more sense - - just maintain a private object reference.
public class foo{
private List<MyObject> myList = null;
public foo(List<MyObject> l){
myList = l;
}
}
Now, the class has the list upon construction, but the list is private to the user. This is a better form of design. It uses composition over inheritance and provides a more loosely coupled design.

Class Specific constants should they be wrapped in a nested class?

If I have constants in a class that are related to each other lets say strings used to write/read Xml file for MyClass, should I wrap them in a nested class Xml inside MyClass? Or just define them without wrapping in MyClass? If it is a good idea to wrap them than what if only part of those constants should be accessible to the outside world for example only the Xml.Name and the rest are Xml attributes that MyClass will use for recreating objects, what would I set the protection level of my nested class to?
I see a nested-class as an object that only makes sense within the context of another object; and whose logic requires properties of this other object. Given that, I've never designed a nested-class that I didn't later refactor away. And I see the perceived need for a public nested-class as a red-flag for a troubled design.
Regardless, your question has me considering whether they are potentially useful. So even though I won't be using this sort of design it may work for you.
I did want to mention that const should only be used for things that never change. Like the hours in a day or the speed of light. I can't exactly tell from your question but something like Xml.Name appears to be variable. I suggest using readonly for these properties. Possibly, static readonly if they're consistent through all instances. This will steer you clear of the many pitfalls of const.
The following is a class I mocked up to demonstrate what I'd recommend for your design:
public class MyClass
{
public string Title { get; set; }
Xml _xml;
public Xml MyXml
{
get { return _xml; }
set { _xml = value; }
}
public MyClass(string xmlName, object xmlAttributes)
{
_xml = new Xml(xmlName, xmlAttributes);
}
public class Xml
{
private readonly string _name;
public string Name
{
get { return _name; }
}
private readonly object _attributes;
internal object Attributes
{
get { return _attributes; }
}
public Xml(string name, object attributes)
{
_name = name;
_attributes = attributes;
}
}
}
I see no need to move the constants to a nested class.
Accessibility:
Make constants only needed by MyClass *private*.
Make constants only needed by classes which are in same assembly as MyClass *internal*.
Make constants only needed by subclasses of MyClass and by MyClass itself protected.
Make constants only needed by classes which are in same assembly as MyClass or by subclasses of MyClass and by MyClass itself internal protected.
Make constants also needed by classes in other assemblies than MyClass's one public.
Naming:
If you have many constants in one class use good prefixes to categories them. So the reader can find faster the right one.

What is a good way to deal with multiple object types in the same form?

I have an abstract base class and two derived classes. The base class contains 6 properties which all can be maintained on a form.
The two derived classed both have 1 extra property. Those two properties can also be maintained on the same form.
In my form I have now code like this:
btnSomething.visible = (myObject is DerivedA);
pnlPanel.visible = !(myObject is DerivedA);
if(myObject is DerivedA)
myBindingSource.DataSource = myObject as DerivedA
mySecondBindingSource = myObject;
I am not very happy with this approach, it smells. So my question is, what is a neat/good way to make this more OO? Because it is possibly that in the future DerivedC comes in...
I think this approach breaks the OCP principle (and probably other principles)
You can use polymorphism and inheritance here:
Define an interface
interface ICommonFeatures
{
bool ContainsFoo {get;}
//yak-yak
}
Then your derived classes implement it
class DerivedA: ICommonFeatures
{
bool ContainsFoo {get {return true;}}
//so-and-so
}
class DerivedB: ICommonFeatures
{
bool ContainsFoo {get {return false;}}
//this-and-that
}
And when you use it, you deal only with the interface
ICommonFeatures foo = new DerivedB();
btnSomething.visible = foo.ContainsFoo;
pnlPanel.visible = foo.Prop2;
myBindingSource.DataSource = foo.CurrentDataSource
A crazy idea would be make the UI extensible.
You could make a form implement a base form.
Then in the derived form class you would only insert the missing controls and behavior for the its model class.
In the derived model class or library you could have some sort binding to the correct form.
A good approach for this would be follow some MVP principles.
Hope it helps you somehow..
I would declare an abstract boolean method/property for each control that need to behave according to the underlying type.
For instance
// to handle pnlPanel.visible = !(myObject is DerivedA);
abstract bool SupportsPanel{get;}
As for your binding sources, I would also provide some virtual BindingSource and SecondBindingSource properties.
Maybe something like (purely an example)
public abstract class BaseClass
{
// All your exising class declaration here
public virtual object BindingSource
{
get
{
// By default, a BaseClass is not valid as a binding source
return null;
}
}
public virtual object SecondBindingSource
{
get
{
// By default, a BaseClass is a valid Second Binding source
return this;
}
}
}
public class DerivedA : BaseClass
{
// All your exising class implementation here
public override object BindingSource
{
get
{
// For DerivedA, the data sourse is itself.
// other classes might have their own implementations.
return this;
}
}
// No need to override SecondBindingSource as the BaseClass one works as expected.
}
So, your code could stop caring about the object type and look like:
myBindingSource.DataSource = myObject.BindingSource;
mySecondBindingSource = myObject.SecondBindingSource;
Hope this helps.

Selecting object from different namespace at run timein c#?

Is it possible to select a namespace for classes at runtime. We have two copies of auto generated objects in different namespaces. Here is an example:
Namespace1
ClassA
ClassB
Namaspace2
ClassA
ClassB
Formerly, the code is simple like below
using Namespace1
...
ClassA.AMethod()
However, we need to select namespace at runtime using a condition variable. Is there a way to define a GetNamespace() method and use it like below or is there any other way you recommend?
GetNamespace().ClassA.AMethod()
Cheers,
Burak
As far as I know, there is no way to dynamically select the namespace, but I think you're in the perfect situation to use a factory. To do so, all your A classes must derive from an abstract one:
namespace Common {
public abstract class AbsA
{
//...
}
public class MyFactory
{
public MyFactory()
{
//...
}
public AbsA getA()
{
AbsA a;
if (condition)
a = new Namespace1.A();
else
a = new Namespace2.A();
return a;
}
}
}
Then you ask your factory for object creation:
MyFactory factory = new MyFactory();
labelMessage.Text = factory.getA().Something;
This complicates your structure a bit, but also makes it more coherent.
Two types from different namespaces are entirely different types as far as the CLR is concerned. Basically you'd need to consider the same solutions as you would for picking between any other arbitrary types... e.g. making both classes implement the same interface, and instead of GetNamespace() returning a namespace, it would have to return the object itself.
Given that you can:
var type = Type.GetType("Namespace1.ClassA");
object instance = Activator.CreateInstance(type);
If you then want to invoke methods on that instance, you need to either cast it to a common interface, or get a MethodInfo instance to invoke. If you control the generation of the classes, I would recommend the interface approach:
public interface IClassA
{
void AMethod();
}
namespace Namespace1
{
public class ClassA : IClassA
{ /* Stuff... */ }
}
That way, you need only:
var type = Type.GetType("Namespace1.ClassA");
IClassA instance = (IClassA)Activator.CreateInstance(type);
instance.AMethod();
Most autogenerated classes using tools such as Linq-to-Sql, Entity Framework, and even WCF proxies are created as partial, which means you can create an additional file, e.g. ClassA.partial.cs and add more to your class declarations without modifying the auto-generated class:
partial class ClassA : IClassA { }

Copying objects to 'this' object in C#

I have a certain hirerchy of classes that needs the capeability to copy all public properties from one object to another.
Each class has a certain set of public properties that might differ from any other class.
Example:
class Base
{
// Common properties/methods...
public void Copy<T>(T data) where T : Base
{
// ...
}
}
class D1 : Base
{
public int ID
{
get;
set;
}
}
class D2 : Base
{
public string Name
{
get;
set;
}
}
Through googling I have read about those methods:
Using reflection
Generating IL code
Serialization
All of them are either very complex or very slow or sometimes both.
Am I missing something? Is there any other way to access the raw this pointer?
EDIT:
I will clerify.
T is of the type of the calling class. For example if it was called by D1 T will always be D1.
The reason for the generic is that I can't really know what T is.
Am I missing something?
Should I just use Base data as the parameter?
What you're missing is that you're asking the compiler to know that T might be one of the types D1 and D2 when all you've said is that T is a Base. How could it possible know what properties or even type your object is as that information is only known at runtime. Even if you could go foreach (PropertyInfo in this.Properties) it's going to find out the name of those properties at runtime so be just as slow as Reflection because how else can it? (it is reflection, just prettier syntax). It can't know what properties are common until it knows what types it's dealing with and you've said "i'm not telling you until runtime" so the answer is "well I'll have to look at runtime" i.e. reflection.
Secondly, just because D1 and D2 might both have a property named Size doesn't mean they are the same property (unless that property is present in a common ancestor).
For example,
ArtilleryAmmo.Shell and
PecanNut.Shell.
AcmeCorp.Staff and GandolfTheWizard.Staff
California.State and MyBrokenEngine.State
LoudSpeaker.Volume and MassiveCrater.Volume
Cave.Bats and BasketballGame.Bats
etc. etc.
You could work around this using an architectural change and use a 'PropertyBag' to store each class' properties.
A PropertyBag is essentially a Dictionary<string, object> where you can give a piece of data a name and add it to the bag. The disadvantage is that everything gets cast to object, so it isn't very type safe plus there's lots of boxing/unboxing, plus the strings as names don't get checked at compile time, so typos are a constant threat.
When you define a property on the class, you store/retrieve the item from the class' propertybag:
public int MyProperty
{
get
{
return (int)_propertyBag["MyProperty"];
}
set
{
if(_propertyBag.Keys.Contains("MyProperty"))
{
_propertyBag["MyProperty"] = value;
}
else
{
_propertyBag.Add("MyProperty", value);
}
}
}
So now to aggregate all the properties of the derived classes, you can expose their 'raw' PropertyBag and iterate through it.
Like I said before, the PropertyBags aren't type-safe, so it you have two classes in the hierarchy with the same property name but different type then you're getting into trouble.
EDIT: If you're concerned with performance, you're going to have to implement this multiple ways and perf test the different implementations -- I can't honestly say if a PropertyBag will actually be faster than using reflection.
The Copy method in the Base class only has access to the properties that are defined in the Base class. You can copy these properties.
But you cannot copy the properties from the subclasses without using something like reflection. But even with reflection you need some kind of knowledge about the mapping of the properties between different subclasses, like copying the ID property to Name.
So you'll need to write separate implementations for each (allowed) subclass conversion.
public interface IBaseCopier<TFrom, TTo> where TFrom : Base, TTo : Base
{
void Copy(TFrom from, TTo to);
}
public class D1ToD2Copier : IBaseCopier<D1, D2>
{
public void Copy(D1 from, D2 to)
{
// Copy properties from the D1 instance to the D2 instance.
}
}
You can register all the ICopier<TFrom, TTo> implementations in a factory class. This class will look up the implementation of the copier, based on the type arguments. If there is no copier for a certain type combination, i.e. the conversion is not supported, the factory should throw an exception.
public class CopierFactory
{
public ICopier<TFrom, TTo> Create<TFrom, TTo>() where TFrom : Base, TTo : Base
{
// Look up the ICopier implementation for the given types.
}
}
Edit
You can use the MemberwiseClone method to create a copy of an object.
public class Base
{
public static T Copy<T>(T data) where T : Base
{
return data.MemberwiseClone() as T;
}
}
If you need more control over the cloning, you can implement the ICloneable interface.
Note: You should realize that you cannot clone a D1 instance into a D2 instance. That would be like cloning a sheep into a horse.
I think the copy method should be inherited by derived classes D1,D2 and their responsibility to copy their own properties to/from other types.
What I would do is create an extension method for the Base class like:
namespace ExtensionMethods
{
public static class MyExtensions
{
public static int CopyTo<T>(this Base source, ref T dest)
{
// Use reflection to cycle public properties and if you find equally named ones, copy them.
}
}
}
Then you could call it in your objects and like:
source.CopyTo<ClassType>(ref this);
I didn't test, so not sure if it would work exactly like described. I did something similar to Cast DataRows into Entities in a big project I worked on.

Categories

Resources