I'd like to create a wrapper class dynamically, such that for every desired class (probably underneath a certain namespace like DBO) I'll get an appropriate class like this:
public class [ClassName]Wrapper{
public [ClassName] [ClassName] { get; set; }
}
Second, I need to if based on wrapper vs original type. I'm assuming I can just do something like:
(classBob as Type).ToString().EndsWith("Wrapper")
If I require anything more, please help me out :).
I'm fairly new to reflection and I've never built a class at runtime. Code to do this would be great, but even pointing out excellent resources to study up on the tools used to do this would be a great move forward for me.
Thanks!
Wouldn't using generics solve your problem?
public class Wrapper<T>
where T : class
{
public Wrapper(T wrappee)
{
Class = wrappee;
}
public T Class { get; } // C# 6.0 Syntax, otherwise add "private set;"
}
Then you can create a wrapper at runtime with
Type typeToBeWrapped = objToBeWrapped.GetType();
Type genericWrapper = typeof(Wrapper<>);
Type constructedWrapper = genericWrapper.MakeGenericType(typeToBeWrapped);
object obj = Activator.CreateInstance(constructedWrapper, objToBeWrapped);
Related
Edit: The main purpose of this question is to gain a deeper understanding of C# and OOP in general. Please keep in mind that I'm not trying to solve a specific problem with this code, but instead just trying to understand how everything works.
I have a way to do this, but I'm wondering if there is another way to do it.
public abstract class ModelBase
{
private const string ERROR = "Error";
public string Status { get; set; }
public string StatusDescription { get; set; }
public static T Error<T>(string errorDescription)
where T : ModelBase, new()
{
var model = new T
{
Status = ERROR,
StatusDescription = errorDescription
};
return model;
}
}
And then to call it:
return ModelBase.Error<ApplicationInit>("Failed to retrieve application segment.");
Where "ApplicationInit" is a derived class of ModelBase.
What would be super cool is if instead, I could call:
return ApplicationInit.Error("Failed to retrieve application segment.");
...And the code would be able to just tell what the derived class is.
IDK, maybe that's not possible...
No. When you declare a static method, there is only one version* of it. The call ModelBase.Error<ApplicationInit>("") and the call ApplicationInit.Error<ApplicationInit>("") will both compile to the exact same bytecode, and a good set of analyzers will flag the latter with a warning.
You can shadow Error with a new static method in ApplicationInit, but that would be a manual process for each new subclass. There is no way^ to generalize it more than you already have.
* A generic method can produce different bytecode for different type parameters, but all such methods are static members of ModelBase, and not any subclass.
^ You could write a source generator to generate these static methods, but that is a lot more work than just using the generic ModelBase.Error<T> method directly.
I've defined a simple interface:
public interface Categorizable {
string Category { get; set; }
}
Elsewhere, I try to use it in a function:
public void Add(Categorizable item)
{
string cat = item.Category;
}
However, Visual Studio tells me "Categorizable does not contain a definition for Category".
How do I fix this so that Category can be used as an accessible property?
Interfaces should really have an I in front of them i. ICategorizable, its very common and a standard for C#.
Check you haven't declared a class with the same name.
Check you haven't declared your interface somewhere else.
If this is coming from a class library, check you are actually using the correct version, and its builds with your project.
Other than this, there isn't much else that can go wrong. This is how interfaces work (without deviation).
My goal is something along these lines:
// Defines members, for the "change-log" of the API,
// if the interface has changed, the API has a new major version.
// For "automatically generating changelogs" (for major versions) of the API
interface IApp
{
static string Name { get; set; }
}
// Internal class, not for usage outside of the dll
internal static class AppConfig
{
internal static bool IsPublished;
}
// Public available members from the API
public static class App : AppConfig, IApp
{
public static string Name { get; set; }
}
Now, there are a few wrongs in the structure above, based on C# language:
The interface cannot have static members
The class App is static, so it cannot inherit a static class
The AppConfig is static, so it cannot be inherited from
The class App is static, so it cannot have an interface
My current "solution":
public static partial class App
{
internal static bool IsPublished;
}
public static partial class App
{
public static string Name { get; set; }
}
Which I wanted to add contracts/interfaces to... So, I would maybe end up with something along these lines, "wrapping" APP:
public static class App
{
private static _App app;
static App()
{
app = new _App();
}
public static string Name { get { return app.Name; } }
}
internal interface _IApp
{
string Name { get; set; }
}
internal class _App : _AppConfig, _IApp
{
public string Name { get; set; }
}
internal class _AppConfig
{
internal static bool IsPublished;
}
This is long, tedious and boring. Three places to update insert a new member: Interface, _App-class (implementation) and in the static App-class (for API-users).
I want to achieve two things: A contract, interface, which defines all major changes from one version to another (read interfaces, print to change-log).
Making things that shall not be used for users of the API private (internal...).
The question? Anyone done something similar before, how did you solve it? Or talk me into forgetting the idea of a changelog based on interfaces... Because interfaces requires non-static objects, while I want static objects (at least on this particular object, it is static!).
PS: Atm. I read all public objects/members of the API to a log, which is now the "changelog". But starting on a new API, wanted to do something... different. :)
Edit: Note; I care about how the object looks on the "other side", it is an important thing. User of the API, to call App-members, shall be as simple as this (straight forward):
System.Windows.App.Name;
Which means the "outer class" (or however you want to look at it), is a static object.
Last note: I have several (12-15) objects of this "type", so I wanted a elegant structure, for all objects, all named similarly, so if you get to know one object, you know them all. Meaning: if one object has an interface, all others has one too. If one object is named "AppConfig", you can bet your life on that the other object also has a class named "OtherConfig". :)
It sounds like you're trying to have different "flavors" of the same class. Each one shares some common functionality? If so, I would use an abstract class as the base instead of an interface. Then, derive the other classes from that one. Unlike an interface, the abstract class will allow you to provide implementations at the parent level (e.g.: saving the object to disk or database). You can read more here: https://msdn.microsoft.com/en-us/library/sf985hc5.aspx.
I also agree with Filkolev, this doesn't sound like something that you would want a static class for.
I have an application which uses plugins. After creating several of them I've found that a big chunk of code is repeated here and there on them so I want to extract a super "plugin base".
Previous the refactor I had the following structure:
After the refactor I have the next one:
I currently don't find a way to model the fact that the plugin engine has a property settings of type plugin settings and the plugin engine base has a property settings of type plugin settings base. I feel that somehow should be a way to declare that the settings property of the plugin engine base should be a "cast" of the settings property of the plugin engine and to model the fact that they both are the same property.
I'm not sure if the problem is explained enough. Feel free to ask for clarifications.
Thanks.
You can use generics. Create generic base class and specify generic parameter constraint to be of type PluginSettingsBase.
abstract class PluginEngineBase<T>
where T: PluginSettingsBase
{
public abstract T Settings { get; set; }
}
Inherit from base class parametrized by PluginsSettings class (thus it is inherited from PluginSettingsBase)
class PluginEngine : PluginEngineBase<PluginsSettings>
{
public PluginSettings Settings { get; set; }
}
Same with PluginData.
An approach I found:
Base class:
class PluginEngineBase
{
public PluginSettingsBase Settings { get; set; }
}
Inheritor:
class PluginEngine : PluginEngineBase
{
public PluginSettings Settings
{
get
{
return (PluginSettings)base.Settings;
}
set
{
base.Settings = value;
}
}
}
If I have a class that is based off another class, how do I access the properties of the first class if it can have any name? I was thinking of using generics to access the properties, but the generics are "generic" for a reason...
For example:
public class AGameInXNA : Microsoft.Xna.Framework.Game
{
int ExampleGameProperty;
}
// ... another class ... //
public class ReferenceToAGameInXNA
{
Game gameInstance;
public void SetGameInstance(Game game)
{
gameInstance = game;
}
public void SetExampleGameProperty()
{
gameInstance.ExampleGameProperty = 21; // I don't know the name of
// AGameInXNA, so I want to
// access it using a generic
// class.
}
}
I know that that does not work, so how would I use generics in this case to access the AGameInXNA's properties in another class if I don't know AGameInXNA's name?
EDIT: I am trying to make it so that I can reuse this code later on. I want to be able to have a class that is unknown, such as public class unknownclassname that extends another class, such as Microsoft.Xna.Framework.Game, and be able to access the class unknownclassname without directly calling/implementing it in the library code.
I would recommend looking into XNA Services.
So for example, you would create a service which could be as simple as an
interface IExamplePropertyService
{
int ExampleProperty { get; set; }
}
public class AGameInXNA : Microsoft.Xna.Framework.Game, IExamplePropertyService
{
int ExampleGameProperty { get; set; }
void Initialize()
{
// Do other initialization
Services.Add( typeof(IExamplePropertyService), this );
}
}
public class ReferenceToAGameInXNA
{
IExamplePropertyService propertyService;
public void GetGameInstance(Game game)
{
propertyService = (IExamplePropertyService)game.GetService( typeof(IExamplePropertyService) );
}
public void SetExampleGameProperty()
{
propertyService.ExampleGameProperty = 21;
}
}
Implement it, and register it with the Game component, then in your ReferenceToAGameInXNA, you would query for this service and store it (rather than the Game) for use later.
As a bonus benefit, The IExamplePropertyService no longer even needs to be implemented by the Game class, it could be implemented by any GameComponent.
This makes for an easy way to seperate classes from having to know about the inner workings of other classes in the Game. So long as the services exist somewhere, your ReferenceToAGameInXNA can be used.
I don't think generics are what you are actually looking for here. In your second class, just change the type of all of the gameInstance to the type of the class you created for your game, in this case AGameInXNA. There should only be a need for one subclass of the Game type in each XNA game. That will allow you to access any public members of AGameInXNA from the Reference class.
If this isn't what you are after, please give a more detailed explanation of what you are trying to accomplish and I'll try to help you.
I don't know XNA, but if you want to have several classes that inherit from Game and have the same property on all of them, you could create an abstract class that inherits from Game and let the other classes inherit from that instead.
(Also, your GetGameInstance() is badly named, because it sets the field, it doesn't get it. And it's probably better as property anyway.)
public abstract class GameBase : Microsoft.Xna.Framework.Game
{
public int ExampleGameProperty { get; set; }
}
public class AGameInXNA : GameBase
{
// code specific to AGameInXNA
}
public class ReferenceToAGameInXNA
{
public GameBase GameInstance { get; set; }
public void SetExampleGameProperty()
{
GameInstance.ExampleGameProperty = 21;
}
}
If the other classed that have ExampleGameProperty shouldn't inherit from Game, you could create an interface instead. AGameInXNA would then inherit from Game directly and it would also implement the interface. And you would work with that interface in ReferenceToAGameInXNA.
using "Game gameInstance;" you can not acess ExmpleProp. You should use "AGameInXNA gameInstance;" too access ExampleProp.