I need to change a specific property dynamically and have been using this snipplet:
var _oldMethod = typeof(TypeName).GetProperty("OldProperty", BindingFlags.Public | BindingFlags.Static).GetMethod;
var _newMethod = typeof(OwnTypeName).GetProperty("NewProperty", BindingFlags.Public | BindingFlags.Static).GetMethod;
ReplaceMethod(_oldMethod, _newMethod);
...
private static unsafe void ReplaceMethod(MethodInfo _oldMethod, MethodInfo _newMethod)
{
var _oldMethodAddress = new IntPtr((int*)_oldMethod.MethodHandle.Value.ToPointer() + 2);
var _destination = (uint*)_oldMethodAddress.ToPointer();
*destination = (uint)_newMethod.MethodHandle.GetFunctionPointer().ToInt32();
}
Unfortunately this required some decompiling with recreating the original property. What I am looking for now is a a possibility to duplicate and kind of backup the original method and dynamically replace the old method with the new one or restore the original one.
Has anyone an idea how to implement this?
Edit:
I may should have clarified my situation further:
public static class ClassName
{
public static bool Property
{
get
{
// Conditions
}
}
}
I can't access ClassName and need to force Property to false in specific situations and need to replace it to the original return value in other situations. I have been using the ReplaceMethod above mentioned but don't want to decompile and rebuild Property from scratch (instead some kind of backup of the original Property)
First of all, you are handling properties instead of methods.
One easy approach to do this is to replace your properties type by Func<> and this will keep what you're wanting to do easier.
private static void Main(string[] args)
{
var a = new A();
a.Property = Method1;
Console.WriteLine(a.Property.Invoke());
a.Property = Method2;
Console.WriteLine(a.Property.Invoke());
Func<string> oldMethod = a.Property;
Console.WriteLine(oldMethod.Invoke());
Console.ReadLine();
}
public class A
{
public Func<string> Property { get; set; }
}
private static string Method1()
{
return "Method1";
}
private static string Method2()
{
return "Method2";
}
You can change the method as many times as you want and also keep the old one in one variable.
Related
How to access and set StaticProperty
public static class StaticClass
{
private bool? _staticValue = null;
public bool StaticProperty => _staticValue ?? ((bool)(_staticValue = GetStaticPropertyValue()));
public static bool GetStaticPropertyValue()
{
//get value
}
}
inside Test Method,
[TestMethod]
public void UnitTestSomeMethod()
{
var consumeClass = new ConsumeClass();
consumeClass.SomeMethod();
}
so that isEnabled variable is set to true in ConsumeClass.SomeMethod
public class ConsumeClass
{
public void SomeMethod()
{
var isEnabled = StaticClass.StaticProperty;
if(isEnabled)
{
//do something
}
}
}
The way your code currently looks like there´s only a dirty way using reflection, because there´s no setter for your property:
var property = typeof(StaticClass).GetProperty("StaticProperty", BindingFlags.Static)?.GetBackingField().SetValue(null, true);
This sometimes is neccessary for large legacy-systems that you can´t easily change but you have the need for unit-tests. However you should change the system as soon as possible, e.g. by using an internal setter:
public static bool StaticProperty { get; internal set; }
and add the InternalsVisibleTo-attribute to your assemby, in order to access its internal members within your test-assembly.
As per your edit the reflection-based approach is a bit easier, as you have a named backing-field which you can assign a new value:
typeof(StaticClass).GetField("_staticValue", BindingFlags.Static).SetValue(null, true);
However be aware that variable-names may change, so the above may fail at runtime when someone renames the backing-field.
Is it possible to get value without creating an instance ?
I have this class:
public class MyClass
{
public string Name{ get{ return "David"; } }
public MyClass()
{
}
}
Now I need get the value "David", without creating instance of MyClass.
Real answer: no. It's an instance property, so you can only call it on an instance. You should either create an instance, or make the property static as shown in other answers.
See MSDN for more information about the difference between static and instance members.
Tongue-in-cheek but still correct answer:
Is it possible to get value without creating an instance ?
Yes, but only via some really horrible code which creates some IL passing in null as this (which you don't use in your property), using a DynamicMethod. Sample code:
// Jon Skeet explicitly disclaims any association with this horrible code.
// THIS CODE IS FOR FUN ONLY. USING IT WILL INCUR WAILING AND GNASHING OF TEETH.
using System;
using System.Reflection.Emit;
public class MyClass
{
public string Name { get{ return "David"; } }
}
class Test
{
static void Main()
{
var method = typeof(MyClass).GetProperty("Name").GetGetMethod();
var dynamicMethod = new DynamicMethod("Ugly", typeof(string),
Type.EmptyTypes);
var generator = dynamicMethod.GetILGenerator();
generator.Emit(OpCodes.Ldnull);
generator.Emit(OpCodes.Call, method);
generator.Emit(OpCodes.Ret);
var ugly = (Func<string>) dynamicMethod.CreateDelegate(
typeof(Func<string>));
Console.WriteLine(ugly());
}
}
Please don't do this. Ever. It's ghastly. It should be trampled on, cut up into little bits, set on fire, then cut up again. Fun though, isn't it? ;)
This works because it's using call instead of callvirt. Normally the C# compiler would use a callvirt call even if it's not calling a virtual member because that gets null reference checking "for free" (as far as the IL stream is concerned). A non-virtual call like this doesn't check for nullity first, it just invokes the member. If you checked this within the property call, you'd find it's null.
EDIT: As noted by Chris Sinclair, you can do it more simply using an open delegate instance:
var method = typeof(MyClass).GetProperty("Name").GetGetMethod();
var openDelegate = (Func<MyClass, string>) Delegate.CreateDelegate
(typeof(Func<MyClass, string>), method);
Console.WriteLine(openDelegate(null));
(But again, please don't!)
You can make that property static
public static string Name{ get{ return "David"; } }
Usage:
MyClass.Name;
You requirements do seem strange, but I think you're looking for some kind of metadata. You can use an attribute to achieve this:
public class NameAttribute : Attribute {
public string Name { get; private set; }
public NameAttribute(string name) {
Name = name;
}
}
[Name("George")]
public class Dad {
public string Name {
get {
return NameGetter.For(this.GetType());
}
}
}
[Name("Frank")]
public class Son : Dad {
}
public static class NameGetter {
public static string For<T>() {
return For(typeof(T));
}
public static string For(Type type) {
// add error checking ...
return ((NameAttribute)type.GetCustomAttributes(typeof(NameAttribute), false)[0]).Name;
}
}
Now this code can get names with and without instances:
Console.WriteLine(new Dad().Name);
Console.WriteLine(new Son().Name);
Console.WriteLine(NameGetter.For<Dad>());
Console.WriteLine(NameGetter.For<Son>());
You can make your property static, as pointed out by many others.
public static string Name{ get{ return "David"; } }
Be aware that this means your instances of MyClass will no longer have their own Name property, since static members belong to the class, not the individual object instances of it.
Edit:
In a note, you mentioned that you want to override the Name property in subclasses. At the same time, you want to be able to access it at the class level (access it without creating an instance of your class).
For the static properties, you would simply create a new Name property in each class. Since they are static, you're always (almost always, yay reflection) going to access them using a specific class, so you'd be specifying which version of Name you want to get. If you want to try and hack polymorphism in there and get the name from any given subclass of MyClass, you could do so using reflection, but I wouldn't recommend doing so.
Using the example from your comment:
public class Dad
{
public static string Name { get { return "George"; }
}
public class Son : Dad
{
public static string Name { get{ return "Frank"; }
}
public static void Test()
{
Console.WriteLine(Dad.Name); // prints "George"
Console.WriteLine(Son.Name); // prints "Frank"
Dad actuallyASon = new Son();
PropertyInfo nameProp = actuallyASon.GetType().GetProperty("Name");
Console.WriteLine(nameProp.GetValue(actuallyASon, null)); // prints "Frank"
}
As a side note, since you are declaring a property that has only a getter and it is returning a constant value, I recommend possibly using a const or static readonly variable instead.
public const string Name = "David";
public static readonly string Name = "David";
Usage for both would be the same:
string name = MyClass.Name;
The main benefit (and drawback) of const is that all references to it are actually replaced by its value when the code is compiled. That means it will be a little faster, but if you ever change its value, you will need to recompile ALL code that references it.
Whenever you write C# code, always check if your method and property getter/setter code does anything at all with other instance members of the class. If they don't, be sure to apply the static keyword. Certainly the case here, it trivially solves your problem.
The reason I really post to this question is that there's a bit of language bias at work in some of the answers. The C# rule that you can't call an instance method on a null object is a specific C# language rule. It is without a doubt a very wise one, it really helps to troubleshoot NullReferenceExceptions, they are raised at the call site instead of somewhere inside of a method where it gets very hard to diagnose that the this reference is null.
But this is certainly not a requirement to the CLR, nor of every language that run on the CLR. In fact, even C# doesn't enforce it consistently, you can readily bypass it in an extension method:
public static class Extensions {
public static bool IsNullOrEmpty(this string obj) {
return obj != null && obj.Length > 0;
}
}
...
string s = null;
bool empty = s.IsNullOrEmpty(); // Fine
And using your property from a language that doesn't have the same rule works fine as well. Like C++/CLI:
#include "stdafx.h"
using namespace System;
using namespace ClassLibrary1; // Add reference
int main(array<System::String ^> ^args)
{
MyClass^ obj = nullptr;
String^ name = obj->Name; // Fine
Console::WriteLine(name);
return 0;
}
Create a static property:
public class MyClass
{
public static string Name { get { return "David"; } }
public MyClass()
{
}
}
Get it like so:
string name1 = MyClass.Name;
That is not possible. As Name is an instance property, you can only get its value if you have an instance.
Also, note that you are not talking about a parameter, but about a property.
Create a static class or a static property, and you don't have to explicitly instantiate it.
This is my first time posting on Stack Overflow, so hopefully I did everything right and you guys can help.
I'm wondering if in C# there's a way to access a static variable belonging to a class, when given only the type of the class. For example:
public class Foo
{
public static int bar = 0;
}
public class Main
{
public void myFunc(Type givenType)
{
int tempInt = ??? // Get the value of the variable "bar" from "Foo"
Debug.WriteLine("Bar is currently :" + tempInt);
}
}
// I didn't run this code through a compiler, but its simple enough
// that hopefully you should get the idea...
It's hard to describe the context of needing to know this, but I'm making a game in XNA and I'm trying to use reference counting to reduce the complexity of the design. I have objects in the game and power-ups that can apply an effect them (that stays on the objects). Power-ups can die but their effects can still linger on the objects, and I need to keep track of if any effects from a power-up are still lingering on objects (thus, reference counting). I plan to make a "PowerUpEffect" class (for each type of power-up) with a static integer saving the number of objects still affected by it, but the design of the rest of the game doesn't work well with passing the PowerUpEffect all the way down to the object for it to call a method of the PowerUpEffect class.
I'm hoping to pass only the PowerUpEffect's type (using something like "typeOf()") and use that type to reference static variables belonging to those types, but I have no idea how to do it or if it's even possible.
I'd be glad to even find work-arounds that don't answer this questions directly but solve the problem in a simple and elegant design. =)
Help! (and thanks!)
If you only have the Type handle, you can do this:
var prop = givenType.GetProperty("bar");
var value = prop.GetValue(null);
I would use a Dictionary instead, which are probably the most concise way of mapping one set of values to another. If you are associating int values with Types, then do something like:
public static readonly Dictionary<Type, int> sTypeValues =
new Dictionary<Type, int>
{
{ typeof(Type1), 5 },
{ typeof(Type2), 10 },
{ typeof(Type3), 2 },
{ typeof(Type4), 3 },
{ typeof(Type5), -7 }
};
your function then becomes:
public void myFunc(Type givenType)
{
int tempInt = sTypeValues[givenType];
Debug.WriteLine("Bar is currently :" + tempInt);
}
int tempInt = (int) givenType.GetField("bar").GetValue(null);
Okay, so you have a collection of powerups, and you want to have an integer associated with each of those powerups. Rather than having a lot of classes, each with a static integer, you can have a single static collection which holds onto all of the powerups and their associated integer values.
public static class MyPowerupInfo
{
public static Dictionary<PowerUp, int> PowerUps {get; private set;}
static MyPowerupInfo
{
PowerUps = new Dictionary<PowerUp, int>();
PowerUps.Add(*some power up object goes here*, 0);
//TODO add other power ups
}
}
Then to use it you can do something like:
int powerupCount = MyPowerupInfo.PowerUps[wickedAwesomePowerup];
or:
public static void IncrementPowerup(Powerup powerup)
{
MyPowerupInfo.PowerUps[powerup] = MyPowerupInfo.PowerUps[powerup]+1;
}
If am getting you correc, this might give you some idea:
using System;
using System.Reflection;
public class RStatic
{
private static int SomeNumber {get; set;}
public static object SomeReference {get; set;}
static RStatic()
{
SomeReference = new object();
Console.WriteLine(SomeReference.GetHashCode());
}
}
public class Program
{
public static void Main()
{
var rs = new RStatic();
var pi = rs.GetType().GetProperty("SomeReference", BindingFlags.Static | BindingFlags.Public); // i have used GetProperty in my case
Console.WriteLine(pi.GetValue(rs, null).GetHashCode());
}
}
Are you assuming if the name of the field you're trying to access (for example, for the class "foo", the field "bar") is a different field based on the Type parameter?
If the name of the field is known based on a finite number of allowable types, you should be able to determine it with a switch statement. For example:
public class Foo
{
public static int bar = 0;
}
public class Baz
{
public static int bing = 0;
}
public class Main
{
public void myFunc(Type givenType)
{
switch (givenType.ToString())
{
case "Foo":
Debug.WriteLine("Bar is currently :" + Foo.bar);
break;
case "Baz":
Debug.WriteLine("Bing is currently :" + Baz.bing);
break;
}
}
}
I have a static Command class like this (but with many more commands):
class GuiCommands
{
static GuiCommands()
{
addInterface = new RoutedUICommand(DictTable.getInst().getText("gui.addInterface"), "addInterface", typeof(GuiCommands));
removeInterface = new RoutedUICommand(DictTable.getInst().getText("gui.removeInterface"), "removeInterface", typeof(GuiCommands));
}
public static RoutedUICommand addInterface { get; private set; }
public static RoutedUICommand removeInterface { get; private set; }
}
It should use my dictionary to get the texts in the right language, which doesn't work, because my dictionary isn't initialized when the static constructor is executed.
My first attempt was to create a new command-class which derives from RoutedUICommand, override the Text property and call the dict in the get method. But the Text property isn't virtual and neither is the GetText()-Method it calls.
The only thing i can think of is provide a static initialize method in this class that translates all the dict-keys. But this is not very clean IMHO because i have to name every command once again like this
addInterface.Text = DictTable.getInst().getText(addInterface.Text);
and if i forget to name one, there won't be an error, just no translation.
I don't even like that i have to name the command twice in this class and once again in the XAML commandbindings.
Do you have any ideas how this can be solved more elegantly?
I like RoutedUICommands much, but like this they're useless to me. Why couldn't Microsoft add the little word 'virtual' a little more often?? (or make it default like JAVA does?!)
I found an acceptable way by translating all commands automatically using reflection.
This way i at least don't have to add all the commands to another method.
I call the translate-method right after i initialized my dictionary.
public static void translate()
{
// get all public static props
var properties = typeof(GuiCommands).GetProperties(BindingFlags.Public | BindingFlags.Static);
// get their uicommands
var routedUICommands = properties.Select(prop => prop.GetValue(null, null)).OfType<RoutedUICommand>(); // instance = null for static (non-instance) props
foreach (RoutedUICommand ruic in routedUICommands)
ruic.Text = DictTable.getInst().getText(ruic.Text);
}
I've got the following class:
public static class Pages
{
public static string LoggedOut = "LoggedOut.aspx";
public static string Login = "Login.aspx";
public static string Home = "Home.aspx";
}
I know I can use Pages.Home statically, but there is a reason for my question.
I wish to have a method that I can call like this:
string pageName = Pages.GetPage("Home");
etc.
C'est possible?
Thanks,
Dave
You can use the following:
var field = typeof(Pages).GetField("Home", BindingFlags.Public | BindingFlags.Static);
var value = (string)field.GetValue(null);
You can do it like Konrad suggested using reflection. But I would consider it much better design to use a dictionary and not rely on reflection for such a task.
public static class Pages
{
private static readonly IDictionary<String, String> PageMap = null;
private static Pages()
{
Pages.PageMap = new Dictionary<String, String>();
Pages.PageMap.Add("LoggedOut", "LoggedOut.aspx");
Pages.PageMap.Add("Login", "Login.aspx");
Pages.PageMap.Add("Home", "Home.aspx");
}
public static GetPage(String pageCode)
{
String page;
if (Pages.PageMap.TryGet(pageCode, out page)
{
return page;
}
else
{
throw new ArgumentException("Page code not found.");
}
}
}
You should of course adjust the error handling to your actual requirements.
Just my tuppence... if you are going to use literals ("Home"), then I would absolutely bind to the const, i.e. Pages.Home (they should probably be constants in the example given). The reflection approach might be handy if you have:
string s = ...something clever...
string page = GetPage(s);
If you do switch to const, then note that they manifest as static fields:
string s = ...something clever...
FieldInfo field = typeof(Pages).GetField(s,
BindingFlags.Static | BindingFlags.Public);
string page = (string)field.GetValue(null);
If it is used heavily you could also cache these in a dictionary.
As other have said, I'd avoid using reflection here. Also, although it adds a bit more code, an enum for the hardcoded page names is also a good idea (also suggested previously)
public enum pages { LoggedOut, Login, Home }
static Dictionary<pages, string> pageDict = new Dictionary<pages, string>() {
{pages.Home, "Home.aspx"},
{pages.Login, "Login.aspx"},
{pages.LoggedOut, "LoggedOut.aspx"}
};
public static string getPage(pages pageName)
{
return pageDict[pageName];
}