Predefined macros for method names - c#

In C++ there are predefined macros such as __FUNCTION__, which compile to a string literal of the function name the macro is used in.
void MyFunc()
{
printf("I'm in %s!", __FUNCTION__); // I'm in MyFunc!
}
Is there anything similar for C#? I am looking to do this for asp.net web forms:
public string MyProperty
{
get { return (string)ViewState[__PROPERTY__]; }
set { ViewState[__PROPERTY__] = value; }
}
Obviously this doesn't work (otherwise I wouldn't ask the question), I would like to know if there's something similar in C# that doesn't use reflection or have any negative performance impacts versus using a string literal "MyProperty".
This will hopefully cut down on typos on my end, but I can think of a few other instances where this would be useful.

C#'s preprocessor doesn't support macros with associated values like C++, but what you're trying to do can be done with compilers that support C# 5.0 and greater (so at least VS2012+) through compiler generated Caller Information. Specifically, via the CallerMemberNameAttribute from the System.Runtime.CompilerServices namespace. Based on your question's code, I created the following example to illustrate how you could go about doing what you want to do:
using System;
class ViewState
{
public string this[string propertyName]
{
get { return propertyName; }
set { }
}
};
class View
{
ViewState mState = new ViewState();
static string GetCallerName(
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
{
return memberName;
}
public string MyProperty
{
get { return (string)mState[GetCallerName()]; }
set { mState[GetCallerName()] = value; }
}
};
class Program
{
static void Main(string[] args)
{
var view = new View();
Console.WriteLine(view.MyProperty);
Console.ReadKey();
}
};
"MyProperty" will be printed to the console. When compiling, the compiler will replace the default value of GetCallerName's memberName argument with the the calling construct's (property, method, etc) name. So there's no code maintenance needed by the programmer
It should also be noted that this has the added benefit of being able to play nice with obfuscation tools, so long as they happen post-compilation.

You could use the StackTrace and StackFrame to get the name of the current method
StackTrace st = new StackTrace();
StackFrame sf = st.GetFrame(1);
string method = sf.GetMethod().ToString();
For properties, the returned method name will include the magic get_ or set_ prefixes.
However, I don't think you can really refactor this into an inline macro or function like you could in C++. But if you do refactor a utility method to DRY this out, you could probably just pop the StackTrace back one step to log the caller's information?

I don't know if there is something like a ViewBag in ASP.NET WebForms. Just in case there isn't, it isn't to difficult to roll you own. You can then wrap the ViewState in that class and get regular property member access like you wish.
public class ExpandoViewState : DynamicObject
{
private readonly StateBag _viewState;
public ExpandoViewState(StateBag viewState)
{
_viewState = viewState;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = _viewState[binder.Name];
if (result != null)
return true;
return base.TryGetMember(binder, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_viewState[binder.Name] = value;
return true;
}
}
...
dynamic state = new ExpandoViewState(ViewState);
var val = (string)state.MyProperty;
state.MyProperty = "hi";

Related

C# - handling session variables like regular variables

My primary problem is, that I have a code, which is full of method calls to set/get session variables which makes the source hard to read. I am searching for a better/simpler/more elegant solution. I tried operator overload in classes, wrapper classes, implicit type conversion, but I run into problems with all of them.
I would like to handle session variables like regular variables.
After reading a lot of articles, I came up with the following solution which I'd like to make even simpler:
public class SV_string
{
private string key = ""; //to hold the session variable key
public SV_string(string key)
{
this.key = key; // I set the key through the constructor
}
public string val // I use this to avoid using setter/getter functions
{
get
{
return (string)System.Web.HttpContext.Current.Session[key];
}
set
{
System.Web.HttpContext.Current.Session[key] = value;
}
}
}
I use the same key as the variable name:
public static SV_string UserID = new SV_string("UserID");
UserID.val = "Admin"; //Now the value assignment is quite simple
string user = UserID.val; //Getting the data is quite simple too
UserID = "Admin"; //but it would be even simpler
So is there any way to get the desired behaviour?
Thanks in advance!
You can create the following Session Wrapper and just add your methods/properties/members to it
public static class EasySession
{
public static string UserId
{
get
{
return Get<string>();
}
set
{
Set(value);
}
}
public static string OtherVariableA
{
get
{
return Get<string>();
}
set
{
Set(value);
}
}
public static <datatype> OtherVariableB
{
get
{
return Get<datatype>();
}
set
{
Set(value);
}
}
static void Set<T>(T value, [CallerMemberName] string key = "")
{
System.Web.HttpContext.Current.Session[key] = value;
}
static T Get<T>([CallerMemberName] string key = "")
{
return (T)System.Web.HttpContext.Current.Session[key];
}
}
You will then use it as follow
EasySession.UserId = "Admin"
Better yet. If you are using C# 6.0 then you can add the following to your namespaces
using System;
using static xxx.EasySession;
This will then allow you to just call
UserId = "Admin"
Here is how it works
[CallerMemberName] will get the name of what is calling Get or Set In this case it will then bassically be "UserId
eg Set("UserId","Admin")
Then it will go and just do the following
System.Web.HttpContext.Current.Session["UserId"] = "Admin";
(Ref:https://msdn.microsoft.com/en-us/magazine/dn879355.aspx)
Just use a property to wrap your session variable in.
There's no need for other parts of your code to know that its implementation, uses a Session variable or what key name it is stored in:
public string UserId
{
get
{
return (string)System.Web.HttpContext.Current.Session["UserId"];
}
set
{
System.Web.HttpContext.Current.Session["UserId"] = value;
}
}
I would suggest to create an interface with operations (no properties), and one concrete implementation of that interface that actually accesses those variables as session variables in the HTTP context; but also another mocked implementation that you can use in your unit tests; as HTTP context is not available in those cases.
So in your code you program against those interfaces, and the concrete implementation is injected at run-time. When the site is starting, it's the concrete implementation that uses Session; from tests, it's the mocked implementation.
The reason to use operations instead of properties would be to explicitly tell the user that you are not merely accessing normal properties, but session variables, that might have important side effects.
Warning: avoid to use static!!! This will cause undesirable side effects, like shared data between different users.

How to handle nameof(this) to report class name

I'd like to use the following C#6 code
var joe = new Self();
Console.WriteLine(joe);
... and get the following output:
joe
The following attempt
class Self {
public string Name { get; set; } = nameof(this);
public override string ToString() {
return Name;
}
}
fails as nameof cannot be applied to this. Is it there a workaround for this problem?
EDIT. The scenario I'm working with assures that no two references point to the same Self object.
No, nameof is designed to refer to the compile-time name of the member you're referring to. If you want an object to have a Name property as part of its state, that is independent of how you get to the Name property - as Frédéric Hamidi says, there could be multiple variables (or none) referring to the same object. Basically you need to differentiate between an object and a variable which happens to refer to that object.
However, if you have a constructor to specify the name, you could then use a couple of tricks to make it easier to get the right name:
class Self
{
public string Name { get; }
public Self([CallerMemberName] string name = null)
{
this.Name = name;
}
}
Then:
class Foo
{
private Self me = new Self(); // Equivalent to new Self("me")
public void SomeMethod()
{
// Can't use the default here, as it would be "SomeMethod".
// But we can use nameof...
var joe = new Self(nameof(joe));
}
}
Maybe you can use the following method:
class Self
{
public override string ToString()
{
return this.GetType().Name;
}
}
You can simply use nameof on the variable itself:
Console.WriteLine(nameof(joe));
Here's a working example using the current Roslyn version
The idea for nameof is to make things type safe for specifying program elements during runtime but with compile time type safety checking.
One should atomize what one wants to display. For example in my error messages I include the pertinent information of the class name and the method as such and its checked, so if I change any of the names they are caught as a compile time error:
class Operation
{
public void Execute()
{
try { ... }
catch (Exception ex)
{
Console.Writeline($"{nameof(Operation)}.{nameof(Execute)} has encountered exception:{Environment.NewLine}{Environment.NewLine}{ex.Message}" );
}
}
}
Output
Operation.Excecute has exception:
...
With that said you should override ToString() and report the class name as such
public override string ToString() { return nameof(Self); }
I usually create an internal constant for it when dealing with long class names:
private const string SomeConst = nameof(Self);
Then you can use that in your code:
Console.WriteLine(SomeConst);

Following the DRY principle in ASP.NET

I have just recently got involved in a classic ASP.NET project which contains lots of storing and reading values from the session and query strings. This could look something like the following:
Session["someKey"]=someValue;
And somewhere else in the code the value in the session is read. Clearly this violates the DRY principle since you'll have the literal string key spread out all over the code. One way to avoid this could be to store all keys as constants that could be referenced everywhere there is a need to read and write to the session. But I'm not sure that's the best way to do it. How would you recommend I best handle this so that I don't violate the DRY principle?
Create a separate public class where you can define your constants, e.g
public class SessionVars
{
public const string SOME_KEY = "someKey";
public const string SOME_OTHER_KEY = "someOtherKey";
}
and then anywhere in your code you can access session variables like this:
Session[SessionVars.SOME_KEY]=someValue;
This way you can get IntelliSence and other bells and whistles.
I think you're reading too much into DRY. I pertains more to things that could be wrapped up in a function. I.e. instead of repeating the same fives lines all over the place wrap those 5 lines in a function and call the function everywhere you need it.
What you have as an example is just setting a value in a dictionary (the session object in this case), and that is the simplest way to store and retrieve objects in it.
I can't remember for the life of me where I humbly re-purposed this code from, but it's pretty nice:
using System;
using System.Web;
namespace Project.Web.UI.Domain
{
public abstract class SessionBase<T> where T : class, new()
{
private static readonly Object _padlock = new Object();
private static string Key
{
get { return typeof(SessionBase<T>).FullName; }
}
public static T Current
{
get
{
var instance = HttpContext.Current.Session[Key] as T;
lock (SessionBase<T>._padlock)
{
if (instance == null)
{
HttpContext.Current.Session[Key]
= instance
= new T();
}
}
return instance;
}
}
public static void Clear()
{
var instance = HttpContext.Current.Session[Key] as T;
if (instance != null)
{
lock (SessionBase<T>._padlock)
{
HttpContext.Current.Session[Key] = null;
}
}
}
}
}
The idea behind it two fold. The type created should be the only type you need. It's basically a big strongly-typed wrapper. So you have some object you want to keep extending information in:
public class MyClass
{
public MyClass()
public string Blah1 { get; set; }
}
Then down the road you extend MyClass and you don't want to have to remember all the Key Values, store them in AppSettings or Const variables in Static Classes. You simply define what you want to store:
public class MyClassSession : SessionBase<MyClass>
{
}
And anywhere in your program you simply use the class.
// Any Asp.Net method (webforms or mvc)
public void SetValueMethod()
{
MyClassSesssion.Current.Blah1 = "asdf";
}
public string GetValueMethod()
{
return MyClassSession.Current.Blah1;
}
Optionally you could place the access to this session object in a base page and wrap it in a property:
class BasePage : Page
{
...
public string MySessionObject
{
get
{
if(Session["myKey"] == null)
return string.Empty;
return Session["myKey"].ToString();
}
set
{
Session["myKey"] = value;
}
}
...
}
Here you are repeating the myKey string but it is encapsulated into the property. If you want to go to the extreme of avoiding this, create a constant with the key and replace the string.

C# Get property value without creating instance?

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.

How can I override get and set methods for all properties in a class?

I have got several classes looking like the one below, and I need to do some checks in the get method and custom set methods. Adding the code in each get and set method makes everything look really messed up.
Is there a way I can override the get and set methods for all properties in an entire class?
public class Test
{
private DataRow _dr;
public Test()
{
_dr = GetData();
}
public string Name
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
}
}
public string Description
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
}
}
public string DescriptionUrl
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)]= value;
}
}
private void VerifyAccess(string propertyname, string classname)
{
//some code to verify that the current user has access to update the property
//Throw exception
}
private DataRow GetData()
{
//Some code to pull the data from the database
}
}
I think what you need is a Proxy on your class, read about Proxy Pattern and Dynamic Proxies
Not directly, there isn't a way to do it with just a compiler. You'd have to generate your entire binary file, then post-process it with some external tool.
This post describes a somewhat similar issue; I hope it helps.
There's a variety of ways to do it.
One would be to create a proxy class (mentioned before), but that would require a lot of refactoring on your behalf.
Another way is with aspects. These do exactly what you're after (insert code based on a pre-requisite.. i.e. all get methods in a class that inherit from x). I ran into a similar problem (actually the exact same problem - checking for security on method calls), and couldn't find cheap/free aspect software that fulfilled my needs.
So, I decided to use Mono-Cecil to inject code before function calls.
If you're interested (it gets a bit messy dealing with IL codes) I can post an old copy of the source
You should extract common code to separate get/set methods, after that you'll be able to add common logic to your properties. By the way, I would do such extraction anyway to avoid copy/paste in the code.
Smth like this:
public string Name
{
get { return GetProperty(MethodBase.GetCurrentMethod()); }
set
{
SetProperty(MethodBase.GetCurrentMethod(), value);
}
}
private string GetProperty(MethodBase method)
{
return _dr[method.Name.Substring(4)].ToString();
}
private void SetProperty(MethodBase method, string value)
{
string methodName = method.Name.Substring(4);
VerifyAccess(methodName , this.GetType().Name);
_dr[methodName] = value;
}
This can be done with indirect value access, e.g. obj.PropA.Value = obj.PropB.Value + 1 -- you can even keep strong typing information. It can be implemented with either attributes or direct-instantiation.
// attribute -- bind later in central spot with annotation application
[MyCustomProp(4)] CustProp<int> Age;
// direct -- explicit binding, could also post-process dynamically
CustProp<int> Age = new CustProp<int>(4, this);
Alternatively, perhaps using a template system such as TT4 may be a viable approach.
However, don't forget "KISS" :-)
I would love for someone to give a better answer for this.
I'm looking for an answer now… best idea I have had would be to define all the properties you want to have be validated as a generic class. For example:
public class Foo {
public String Name {
get{ return _Name.value; }
set{ _Name.value = value; }
}
private Proxy<String> _Name;
static void main(String[] args) {
Foo f = new Foo();
//will go through the logic in Proxy.
f.Name = "test";
String s = f.Name;
}
}
public class Proxy<T> {
public T value {
get {
//logic here
return _this;
} set {
//logic here
_this = value;
}
}
private T _this;
}

Categories

Resources