Interfacing common functionality between controls - c#

I'm not really sure how to ask this question. Suppose I have a class that needs to access certain properties of a Control (for example, Visible and Location). Perhaps I want to use the same class to access properties of another item that have the same name, but the class might not derive from Control. So I tried making an interface:
public interface IThumbnail {
bool Visible { get; set; }
int Height { get; set; }
int Width { get; set; }
Image Image { get; set; }
Point Location { get; set; }
event EventHandler Click;
}
Note that, for example, PictureBox happens to implement this interface. However, because the class definition does not say that it implements IThumbnail, I can't cast PictureBoxes to IThumbnails--I get an InvalidCastException at runtime. But why can't the CLR 'figure out' that PictureBox really does implement IThumbnail (it just doesn't explicitly say it does).
Also, what should I do to handle this situation? I want a way to access some of the PictureBox's properties without having my class know it's modifying a PictureBox.
Thx, Sam
PS- I'm a newbie to interface programming, so I apologize if this is a stupid q.

It's not a stupid question, it's a good one. :)
What you're asking for on the interface is commonly referred to as "duck-typing." It isn't supported right now, but C#4.0 will support it via the new "dynamic" keyword.
You've really got three choices that I'm aware of at this point:
You can go up the tree until you find the common ancestor (probably Component) and then downcast to your supported types. If the downcast fails, you throw or handle appropriately.
Pro: Minimal code duplication.
Con: You're trading away compile-time type safety for runtime type safety. You have to add error checking/handling for invalid casts.
Code:
public void UseThumbnail(Component c)
{
PictureBox p = c as PictureBox;
if(p != null) // do whatever
// so forth
}
You can duplicate functionality as appropriate for everything that you need to implement this functionality for.
Pro: Maintain compile time type safety
Con: You're duplicating code for different types. This can grow into a significant maintenance burden, especially if you're handling more than two similar classes.
Code:
public void UsePictureBox(PictureBox p)
{
// Some code X
}
public void UseOtherControl(OtherControl p)
{
// Some code X
}
You can create your special interface and subclass the classes you want to support to expose that common functionality.
Pro: You get compile time safety and can program against your new interface.
Con: You have to add an empty subclass for everything you're dealing with, and you need to use them.
Code:
public class ThumbnailPictureBox : PictureBox, IThumbnail
{ }

I guess you would have to make you own class that derives from PictureBox. That new class would also implement IThumbnail.
public class MyPictureBox : PictureBox, IThumbnail {
}

The CLR can't figure out that PictureBox implements the same method signature as IThumbnail because it's just not supported yet. The feature you are talking about here is often reffered to as Duck Typing, and it's a feature of dynamic languages such as Ruby - it should be available in .NET and C# with the next release (C# 4) and the DLR (dynamic language runtime).
To get the functionality you require right now, you can write a class that implements the IThumbnail interface and encapsulates an instance of a PictureBox.
public class ThumbnailPictureBox
{
private PictureBox _pictureBox;
public ThumbnailPictureBox(PictureBox pictureBox)
{
_pictureBox = pictureBox;
}
public bool Visible
{
get { return _pictureBox.Visible; }
set { _pictureBox.Visible = value; }
}
// etc...
}

If the class you're interested in creating an interface for is not "sealed" then your could create a new class and inherit from the non-sealed class, implementing the interface.
If it were sealed (and I don't think PictureBox is) you'd probably want to build a wrapper class that implements the interface that you're interested in and contains a PictureBox control, exposing only the members that you're interested in.

You could create your own class that implements the interface and has a PictureBox behind the scenes
class MyPictureBox: IThumbnail
{
private PictureBox _pictureBox = new PictureBox();
bool Visible
{
get
{
return _pictureBox.Visible;
}
set
{
_pictureBox.Visible = value;
}
}
//implement the rest, you get the idea
}
This pattern would also be useful in the event that you want to extend a 3rd party's "PictureBox" that is sealed, in which case you would not be abel to extend from it.
Actually Derik Whittaker just did a nice podcast on this pattern at dimecasts.net here

There are hundreds of interfaces in the .net runtime. If interfaces were left to be implicitly implemented, and the compiler were to go through and match up interfaces automatically to classes, every class you program could be matched to interfaces that you didn't even want it to.
As the other posters have suggested, your situation is exactly what OO is meant to solve ;)
Try extending PictureBox to implement your interface.

The situation you are describing is exactly what Interfaces are for
public interface IThumbnail
{
bool Visible {get; set;}
string FilePath {get; set;}
}
public class Bar : IFoo
{
bool Visible {get; set;}
int SomeNumber {get; set;}
/*
rest of Bar functionality
*/
}
public class SomeClass
{
public void DisplayThumbnail(IThumbnail thumb)
{
//Do Stuff to things.
}
}
Once it is implemented that way, for any aspect of your program that shouldn't have access to any Bar functionality, but SHOULD have access to any IThumbnail functionality, just pass them an object of type IThumbnail
Bar bar = new Bar();
SomeClass someClass = new SomeClass();
someClass.DisplaySomething((IThumbnail) bar);
Now the DisplaySomething function cannot access any Bar exclusive functionality. It can only access the IThumbnail specific parts of it.
EDIT
This question deals with the same issue
Will C#4.0 allow dynamic casting, If not, should it?

Related

Access abstract class members from childs inherits

I have an abstract class called Flight and its implement a interface called IFlight and it has a virtual method, another three classes that inherit from it, the only diffrence between those three classes is the implemantation of this method. Another thing that I want to do is implement a method that accepts as an argument an object of type IFlight (could be one of those three classes) and from them i want to access the members of the abstract class (Flight). Which way there is to implement such thing ?
Flight:
class AbsFlight: IFlight
{
public int ID { get; set; }
public string Start_Point { get; set; }
public virtual float Calculate_Price(float Base_Price)
{
return Base_Price;
}
}
One of the classes (The other two looks similar except the method "Calculate_Price"):
class Charter: AbsFlight
{
public override float Calculate_Price(float Base_Price)
{
return base.Calculate_Price(Base_Price) * 3;
}
}
Main:
private static void Some_Method(IFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2)); //OK
Console.WriteLine(flight.ID); //Error
}
static void Main(string[] args)
{
List<IFlight> flights = new List<IFlight>();
flights.Add(new Regular());
flights.Add(new Charter());
flights.Add(new LowCost());
Main_SomeMethod(flights[0]);
}
Your current solution, in combination with some of the suggestions, will be a case of a mounted riding rider. You don't need an interface and a base class and testing for type.
You can solve your problem the way you're trying, with a base class and an interface. But it's overkill, and you have to kind of duplicate some stuff in the interface and the base class.
You can solve your problem with a simple base class and three derived classes where only Calculate_Price gets overridden. Put the common items in the base class. This is a very simple solution, easy to figure out, especially if C# and OOP is new to you.
You can also solve your problem with an interface and three classes, not derived. This has the disadvantage that you have to implement the interface in three classes. As Peter Csala points out, C# 8 has some language features that can help minimize this work, possibly making this just as simple as using only a base class and no interface. I am not too familiar with those features, so I can't judge whether it makes sense.
Then there is another option entirely. This touches on what zaitsman hinted at - that this is possibly an XY problem. Why do you want to distinguish between Regular, Charter and LowCost using classes derived from Flight/AbsFlight? Is it possible to just have an attribute that tells what price profile is used? Are there other fields and properties of a Flight that has nothing to do with the price, and yet also distinguishes flights? Perhaps just use one class.
About testing for class type. This is what we call code smell. Generally, if you test for class types a lot, then you defy the purpose of using classes and/or interfaces in the first place.
Your method should accept the type that has the properties it needs, in this case the AbsFlight class.
private static void Some_Method(AbsFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2));
Console.WriteLine(flight.ID); //OK
}
But let's says the method must accept any IFlight. In this case, it can't be sure it received an AbsFlight; it has to check. After the check you can just cast.
private static void Some_Method(IFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2));
if (flight is AbsFlight)
{
Console.WriteLine(((AbsFlight)flight).ID); //OK
}
}
With c#7 there is an additional construct you can use, if you think it is clearer:
private static void Some_Method(IFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2));
switch (flight)
{
case AbsFlight absFlight:
Console.WriteLine(absFlight.ID); //OK
break;
}
}
It seems to be that you are doing something wrong that this is your requirement.
When you use an interface and pass it as an argument you want it to be common to all the objects that implement it.
Anyway, if you do want to do it. You might do something like:
if (flight is Flight)
{
Flight yourFlight = (Flight)flight;
// Here you can use anything you need from Flight, e.g: yourFlight.ID
}

C# Creating an object within a class

I'm making a map loading system that uses chunks so that the entire map data doesn't have to be loaded at once.
I have a "World" class, and within that class I'm creating an instance of a class called "ChunkManager".
I'm unsure if creating an instance inside another class is a good idea/considered a "normal" thing to do etc. I've not been able to find anything about this while searching the internet.
So my question is: Should I be creating an instance of a class within a class in the way I have, or will there be problems with doing it this way?
Here is my code, if it's relevant:
class World
{
public string WorldName { get; set; }
ChunkManager chunkManager = new ChunkManager();
public World(string worldName)
{
WorldName = worldName;
}
public void AddChunk(int X, int Y)
{
//Plus other validation code here that I didn't paste
chunkManager.AddChunk(X, Y);
}
}
And ChunkManager:
class ChunkManager
{
public int TotalGeneratedChunks { get; private set; }
private List<Chunk> ChunkList = new List<Chunk>();
public bool CheckIDExists(int IDToCheck)
{
foreach (Chunk i in ChunkList)
{
if (i.UniqueID == IDToCheck)
{
return true;
}
}
return false;
}
public void AddChunk(int X, int Y)
{
ChunkList.Add(new Chunk(TotalGeneratedChunks++, X, Y));
}
}
Your code is fine BUT if either class grows to be more complex and you want to be able to test them independently you should instead define an interface IChunkmanager and inject an instance of ChunkManager into World:
class World
{
public string WorldName { get; set; }
private readonly IChunkManager chunkManager;
public World(string worldName, IChunkManager chunkmanager)
{
this.chunkManager = chunkManager;
...
With this approach you can use a mocking framework to inject a mock IChunkManager and can test the World class independently.
In general classes should be loosely coupled. As soon as you new-up an instance of another class within a class you have tightly-bound them in a way that makes it hard to test them independently (or to reuse them in different situations).
It's perfectly fine to create an instance of a class inside another. chunkManager is what is known as a field and the syntax for initializing it inline along with its declaration is called an initializer. You can find more information on initializers and how they are different from initializing via the constructor in this blog series by Eric Lippert
Part 1
Part 2
It might some times be a better idea to initialize fields via the constructor though as this lets you use dependency injection (parameter injection to be precise) which can greatly improve the testability and modularity of your code. If you're interested in learning more about dependency injection I suggest purchasing and reading this book.
Standard practice is to set values inside the constructor because it allows for dependency injection and makes modifying the constructor to use an argument trivially easy.
If you are going to create a lot of World, i suggest creating an Abstract base that implements the ChunckManager.
That way you can leverage the use of base class, promote code reuse. You can also make your ChunkManager singleton since it only needs to be used by the base, and then use a method to actually instantiate the ChunkManager if you need specific properties from maps.
Use DI to pass the prop from child to base to instantiation of the ChunkManager
yes you can use one class type in another class its like one of filed on this class like when you use string a=new string() you use an object of class string its normal code

OOP principles in C#

I have a library (no source), to an certain object of which, I need to add some properties.
What would be the a way to do it ? I'm aware I could extend the class and add properties to the child. As well I know there are NO Extension Properties in C# yet. What would you suggest ? Thank you !
The metadata of class could be something like :
public class ResultClass
{
public IList<Item> Results { get; set; }
public int TotalResults { get; set; }
}
and I want to add a :
String description;
to it. Thanks.
There are a couple strategies you could take. Inheritance is the most obvious one. You might also consider composition. Can you give us some more details about what the object is and what properties you need to add to it and why?
After seeing the expanded question:
Either strategy outlined above (composition or inheritance) will probably work for you. Personally, I prefer composition. I think it better insulates you from changes that might be made to the third party library. It also forces you to work through the public interface of the library class, which is preferable when you have no knowledge or control of the internals of a class.
Here is the most basic example of composition.
public CompositeClass
{
private ResultClass _resultClass = new ResultClass();
public IList<Item> Results
{
get { return _resultClass.Results; }
set { _resultClass.Results = value; }
}
public int TotalResults
{
get { return _resultClass.TotalResults; }
set { _resultClass.TotalResults = value; }
}
//
// New Property
//
public string Description { get; set; }
}
Why do you need to add properties? If this is for binding purposes then I would suggest creating a wrapper class or creating your own inherited type that can raise PropertyChanged events in response to various state changes in your third party types. Instead of telling us your proposed solution you should tell us the actual problem you are trying to solve. Also (as I can't vote to close/migrate), this is not really a valid discussion for this site.
I think you are mixing up Extension Methods with Extension Properties.
And the last ones do not exist in C#.
So you should extend the class or create an inheriting class.

Appropriate design/design pattern for this problem?

I previously posted this, but I guess it was too verbose and irrelevant. My question is also like this. One poster in the second link said the answer (of why you can't do the code below) was a problem of design, specifically "bad use of inheritance". So I'd like to check this issue again with the experts at StackOverflow and see if this is really an issue of "bad inheritance" - but more importantly, how to fix the design.
Like the poster, I'm also confused about the Factory method and how I can apply it. It seems the factory method is for multiple concrete classes that have the exact same implementation as the abstract base class and do not add their own properties. But, as you will see below, my concrete classes build upon the abstract base class and add extra properties.
The Base Class We Build Upon:
public abstract class FlatScreenTV
{
public string Size { get; set; }
public string ScreenType { get; set; }
}
Extension Class Examples:
public class PhillipsFlatScreenTV : FlatScreenTV
{
// Specific to Phillips TVs. Controls the backlight intensity of the LCD screen.
public double BackLightIntensity { get; set; }
}
public class SamsungFlatScreenTV : FlatScreenTV
{
// Specific to Samsung TVs. Controls the time until the TV automatically turns off.
public int AutoShutdownTime { get; set; }
}
Let's say there are more extension classes for more brands of flat screen TVs. And then, let's say we stick them all into a generic List:
public static void Main()
{
List<FlatScreenTV> tvList = new List<FlatScreenTV>();
tvList.Add(new PhillipsFlatScreenTV());
tvList.Add(new SamsungFlatScreenTV());
tvList.Add(new SharpFlatScreenTV());
tvList.Add(new VizioFlatScreenTV());
FlatScreenTV tv = tvList[9]; // Randomly get one TV out of our huge list
}
The Problem:
I want to access the specific properties of whatever 'original' brand TV this variable belongs to. I know the brand because if I call tv.GetType(), it returns the correct 'original' type - not FlatScreenTV. But I need to be able to cast tv from FlatScreenTV back to its original type to be able to access the specific properties of each brand of flat-screen TVs.
Question #1: How can I dynamically cast that, properly - without makeshift hacks and huge if-else chains to brute-guess the 'original' type?
After browsing around similar design issues, most answers are: you can't. Some people say to look at the Factory Pattern, and others say to revise the design using interfaces, but I don't know how to use either to solve this problem.
Question #2: So, how should I design these classes so that I can access the original type's specific properties in the context above?
Question #3: Is this really bad inheritance?
Your design violates the "Liskov Substitution Principle". In other words, the code that deals with items from your list of FlatScreenTV shouldn't know or care what derived type is.
Say your code needs to create a custom remote control GUI. It might be enough to simply know the names and types of the properties of each TV to auto-generate the UI. In which case you could do something like this to expose the custom properties from the base class:
public abstract class FlatScreenTV
{
public FlatScreenTV()
{
CustomProperties = new Dictionary<string,object>();
}
public Dictionary<string,object> CustomProperties { get; private set; }
public string Size { get; set; }
public string ScreenType { get; set; }
}
public class PhillipsFlatScreenTV : FlatScreenTV
{
public PhillipsFlatScreenTV()
{
BackLightIntensity = 0;
}
// Specific to Phillips TVs. Controls the backlight intensity of the LCD screen.
public double BackLightIntensity
{
get { return (double)CustomProperties["BackLightIntensity"]; }
set { CustomProperties["BackLightIntensity"] = value; }
}
}
public class SamsungFlatScreenTV : FlatScreenTV
{
public SamsungFlatScreenTV()
{
AutoShutdownTime = 0;
}
// Specific to Samsung TVs. Controls the time until the TV automatically turns off.
public int AutoShutdownTime
{
get { return (int)CustomProperties["AutoShutdownTime"]; }
set { CustomProperties["AutoShutdownTime"] = value; }
}
}
If you really do need to be working directly with the derived types, then you should instead consider moving to a plugin based architecture. For example, you might have a factory method like this:
IRemoteControlGUI GetRemoteControlGUIFor(FlatScreenTV tv)
which would scan your plugins and find the one that knew how to build the UI for the particular type of FlatScreenTV you passed in. This means that for every new FlatScreenTV you add, you also need to create a plugin that knows how to make its remote control GUI.
Factory Pattern would be the best way to go
I can offer a partial answer:
Firstly read up on Liskov's Substitution Principle.
Secondly you are creating objects that inherit from FlatScreenTV, but apparently for no purpose as you want to refer to them by their SubType (SpecificTVType) and not their SuperType (FlatScreenTV) - This is bad use of Inheritance as it is NOT using inheritance lol.
If your code wants to access properties particular to a given type, then you really want this code encapsulated within that type. Otherwise everytime you add a new TV type, all the code that handles the TV list would need to be updated to reflect that.
So you should include a method on FlatScreenTV that does x, and override this in TV's as required.
So basically in your Main method above, instead of thinking I want to be dealing with TVTypeX, you should always refer to the basetype, and let inheritance and method overriding handle the specific behaviour for the subtype you are actually dealing with.
Code eg.
public abstract class FlatScreenTV
{
public virtual void SetOptimumDisplay()
{
//do nothing - base class has no implementation here
}
}
public class PhilipsWD20TV
{
public int BackLightIntensity {get;set;}
public override void SetOptimumDisplay()
{
//Do Something that uses BackLightIntensity
}
}
"the factory method is for multiple concrete classes that have the exact same implementation as the abstract base class [interface] and do not add their own properties."
No, speaking more practical, than theorical, the factory method can provide you with objects of concrete classes, in which the concrete classes, must have some common methods and interfaces, but, also some additional specific attributes.
Sometimes I use a method that creates the same class object every time I called, and I need to call it several times, and sometimes I use a method that create several different class objects, and that maybe be confusing, maybe another question.
And, your further comment about a switch sentence, with many options, when using the factory pattern, you usually provide an identifier for the concrete class / concrete object. This can be a string, an integer, an special type id, or an enumerated type.
You could use an integer / enum ID instead, and use a collection to lookup for the concrete class.
You can still leverage a factory. The point of a factory IMO is to put all the heavy lifting of constructing your various TVs in one place. To say categorically "a factory is for multiple concrete classes that have the exact same implementation as the abstract base class" is forgetting about polymorphism.
There is no law that says you cannot use a factory pattern because the sub classes declare unique properties and methods. But the more you can make use of polymorphism, the more a factory pattern makes sense. Also as a general guideline, IMHO, the more complexity that must go into constructing from the base the better off you are in the long run using a factory because you are "encapsulating change" - that is, constructing concrete classes is likely to change due to differing requirements and inherent construction complexity (a design analysis decision, to be sure) . And that change is in a single class - the factory.
Try this: Define everything in the abstract class and then for a given TV subclass either write concrete-specific code, and for those that don't apply write some standard "I don't do that" code.
Think about all the things your TVs do in generic terms: turn on, turn off, etc. Write a virtual method shell in the base class for all the generic things a TV does - this is a simple example of the template method pattern by the way. Then override these in the concrete classes as appropriate.
There are other things you can do in the base class to make it more fundgeable (that's a technical term meaning "reference subclasses as the base class, but do sub-classy things").
Define delegate methods (very powerful yet under-utilized)
use params[] for dynamic method parameter lists
Make Property delegates
Static methods
Declare Properties and methods "abstract" - forces sub-class implementation, vis-a-vis "virtual"
Hide inherited stuff in the sub class (generally using "new" keyword to communicate that it's on purpose)
If construction parameters are numerous or complex, create a class specifically designed to pass configuration to the factory's build method.
public class TVFactory {
public TV BuildTV(Brands thisKind) {
TV newSet;
switch (thisKind) {
case Brands.Samsung :
Samsung aSamsungTV = new Samsung();
aSamsungTV.BacklightIntensity = double.MinVal;
aSamsungTV.AutoShutdownTime = 45; //oops! I made a magic number. My bad
aSamsungTV.SetAutoShutDownTime = new delegate (newSet.SetASDT);
newSet = aSamsungTV;
break;
. . .
} // switch
}
//more build methods for setting specific parameters
public TV BuildTV (Brands thisKind, string Size) { ... }
// maybe you can pass in a set of properties to exactly control the construction.
// returning a concrete class reference violates the spirit of object oriented programming
public Sony BuildSonyTV (...) {}
public TV BuildTV (Brands thisKind, Dictionary buildParameters) { ... }
}
public class TV {
public string Size { get; set; }
public string ScreenType { get; set; }
public double BackLightIntensity { get; set; }
public int AutoShutdownTime { get; set; }
//define delegates to get/set properties
public delegate int GetAutoShutDownTime ();
public delegate void SetAutoShutDownTime (object obj);
public virtual TurnOn ();
public virtural TurnOff();
// this method implemented by more than one concrete class, so I use that
// as an excuse to declare it in my base.
public virtual SomeSonyPhillipsOnlything () { throw new NotImplementedException("I don't do SonyPhillips stuff"); }
}
public class Samsung : TV {
public Samsung() {
// set the properties, delegates, etc. in the factory
// that way if we ever get new properties we don't open umpteen TV concrete classes
// to add it. We're only altering the TVFactory.
// This demonstrates how a factory isolates code changes for object construction.
}
public override void TurnOn() { // do stuff }
public override void TurnOn() { // do stuff }
public void SamsungUniqueThing () { // do samsung unique stuff }
internal void SetASDT (int i) {
AutoShutDownTime = i;
}
}
// I like enumerations.
// No worries about string gotchas
// we get intellense in Visual Studio
// has a documentation-y quality
enum Brands {
Sony
,Samsung
,Phillips
}

Class extending - best practice/best solution

First thing to note - I KNOW DELEGATION AND DECORATOR PATTERNS!
Second - I am using C# .NET 4.0, so if you come up with a solution that is specific for it, that's fine. But if solution will work for any OOP language and platform, that would be great.
And here the question goes...
I have a partial class (lets name it Class1), which I cannot modify. Thus, I can just extend it or/and inherit from it. This class provides a perfect data model for me, the only thing I need is to add some attributes to its properties (for validation, defining label text value in MVC etc - for now, I do not need answers like 'you can do what you need without attributes', that's not the matter of my question).
It is not a problem to use another class as a data model, so I can, say, create Class2 : Class1 and use Class2 as a model. Properties that need attributes would be defined as public new <type> <propertyname>. This will limit me to rewriting only the properties that need attributes, leaving all other untouched.
The smaller problem is that I do not what to redefine getters and setters for the properties, as all they gonna contain is return base.<propertyname> and base.<propertyname> = value, and if there are lots of such properties, this means lots of "stupid" coding. Is there a way to avoid this?
The bigger problem is that I have to parametrize my Class2 with Class1 instance and make something like class2.<propertyname> = class1.<propertyname> for each single property I have - too much of "stupid" coding. I can avoid it using reflection - find all properties with public getters and setters in Class1 and call prop.SetValue(child, prop.GetValue(parent, null), null); in the loop. This provides a generic function for simple cases, which is quite fine, as I mostly have simple models - lots of properties with public getters and setters without body and another logic. But I want more generic solution, and I do not like reflection. Any ideas?
Here goes the full code of the extension method that creates Class2 basing on Class1
public static Child ToExtendedChild<Parent, Child>(this Parent parent)
where Child : Parent, new()
{
Child child = new Child();
var props = typeof(Parent).GetProperties().Where(p => p.GetAccessors().Count() >= 2);
foreach (var prop in props)
{
prop.SetValue(child, prop.GetValue(parent, null), null);
}
return child;
}
(by the way, this method may not ideally implement my solution, so any corrections would also be appreciated)
Thanks in advance!
The smaller problem doesn't seem to be much of a problem. Maybe I'm misunderstanding the question, but assuming you're simply deriving a subclass, there should be no reason to redefine either the properties or their associated getters/setters.
The bigger problem might be resolved using something a little simpler. Using reflection for a lot of your object initialization seems a little expensive. If you're dealing with a class that is primarily a big bag or properties, maybe you should as if you need access to all of those properties in any given situation. You mention MVC and validation, is the entire model being used in the controller method you're validation is taking place in? If not, why not look at using a viewmodel that only exposes those pieces you need in that method?
Your reflection initializer is interesting, but if you're going to be doing a lot of this then you might consider investing a little time with Automapper. Otherwise maybe consider moving away from a generic solution to something that just tackles the problem at hand, i.e. mapping properties from an instance of an object to another instance of a derived object. Maybe you can create a copy constructor in the parent class and use that in your derived class?
public class Foo {
public string PropOne { get; set; }
public string PropTwo { get; set; }
public Foo(string propOne, string propTwo) {
PropOne = propOne;
PropTwo = propTwo;
}
public Foo(Foo foo) {
PropOne = foo.PropOne;
PropTwo = foo.PropTwo;
}
}
public class Pho : Foo {
// if you have additional properties then handle them here
// and let the base class take care of the rest.
public string PropThree { get; set; }
public Pho(string propOne, string propTwo, string propThree)
: base(propOne, propTwo) {
PropThree = propThree;
}
public Pho(Pho pho) : base(pho) {
PropThree = pho.PropThree;
}
// otherwise you can just rely on a copy constructor
// to handle the initialization.
public Pho(Foo foo) : base(foo) {}
}
I assume the partial class is generated code, it makes the most sense given your scenario.
I know of one way to do this, but depending on how the attribute gets crawled, it may not work.
// Generated Code
public partial Class1
{
public string Foo { get { ... } }
}
// Your Code
public interface IClass1
{
[MyAttribute]
public string Foo { get; }
}
public partial Class1 : IClass1
{
}
If someone were to look at attributes by using GetCustomAttributes with inheritance, then I think they would get this attribute.
As an aside, whenever I see generated code that doesn't have virtual properties it makes me cry a little bit inside.
To address your bigger question, why don't you just make Class2 a wrapper for Class1. Instead of copying all of the properties you can just give Class2 an instance of Class1 in the constructor, store it locally and make all of your properties pass-throughs. It means some hand coding, but if you're building a Class2 by hand anyway and want to decorate it with a bunch of attributes, well, you're hand coding Class2 anyway.

Categories