c# Full Name of Property in Class - c#

I have a class
public class MyCoolProp
{
public string FullName {get;set;}
}
and in another Class i have this as Property:
public class MyMainClass
{
public MyCoolProp coolprop {get;set;}
public void DoSomething()
{
MessageBox.Show(nameof(coolprop.FullName));
}
}
The Actual Result is: "Fullname"
But i want a combination like this: "coolprop.FullName"
i dont want to do something like this:
nameof(coolprop) + "." + nameof(coolprop.FullName);
Maybe its possible in an extension?
If i rename the Property "coolprop" the output should also have the new name

Depending on exactly what you want to do, you might be able to use CallerArgumentExpressionAttribute. That does mean you need to be willing to actually evaluate the property as well, even if you don't use it.
Note that this requires a C# 10 compiler.
Here's a complete example:
using System.Runtime.CompilerServices;
public class MyCoolProp
{
public string FullName { get; set; }
}
class Program
{
static MyCoolProp CoolProp { get; set; }
static void Main()
{
CoolProp = new MyCoolProp { FullName = "Test" };
WriteTextAndExpression(CoolProp.FullName);
}
static void WriteTextAndExpression(string text,
[CallerArgumentExpression("text")] string expression = null)
{
Console.WriteLine($"{expression} = {text}");
}
}
Output: CoolProp.FullName = Test

Source:
get name of a variable or parameter (modified a bit adjusted with your case)
You can use what System.Linq.Expression provides
code example:
using System.Linq.Expression
class Program
{
public static MyCoolProp coolProp { get; set; }
static void Main(string[] args)
{
coolProp = new MyCoolProp() { FullName = "John" };
DoSomething();
}
public static string GetMemberName<T>(Expression<Func<T>> memberExpression)
{
MemberExpression expressionBody = (MemberExpression)memberExpression.Body;
return expressionBody.ToString();
}
public static void DoSomething()
{
string prop = GetMemberName(() => coolProp.FullName);
Console.WriteLine(prop);
}
}
public class MyCoolProp
{
public string FullName { get; set; }
}
the GetMemberName method will return the namespace, class name, object name, and variable name (depends where the method is being called)
Output: Program.coolProp.FullName

Related

setting a static variable in a static class depending on the calling class

Static class code :
static public class CommonValues
{
public static string _consumerName;
}
Assigning from a non-static class :
public class CreateSessionConsumer : IClassFixture<CommonFixture>
{
private IMockProviderService _mockProviderService;
private string _mockProviderServiceBaseUri;
public string _path = "/Security/CreateSession";
public CreateSessionConsumer(CommonFixture fixture)
{
Common.CommonValues._consumerName = "CreateSessionConsumer";
Common.CommonValues._providerName = "CreateSessionAPI";
_mockProviderService = fixture.MockProviderService;
_mockProviderService.ClearInteractions(); //NOTE: Clears any previously registered interactions before the test is run
_mockProviderServiceBaseUri = fixture.MockProviderServiceBaseUri;
CommonFixture.PactDirectory=#"..\pacts";
//CommonFixture.Provider=_provider;
}
}
Accessing in this static variable in a generic method:
public class CommonFixture : IDisposable
{
public IPactBuilder PactBuilder { get; private set; }
public IMockProviderService MockProviderService { get; private set; }
public int MockServerPort { get { return 9222; } }
public string MockProviderServiceBaseUri { get { return String.Format("http://localhost:{0}", MockServerPort); } }
public static string PactDirectory { get; set; }
public CommonFixture()
{
var pactConfig = new PactConfig
{
SpecificationVersion = "2.4.6",
PactDir = #"..\..\..\..\..\pacts",
LogDir = #".\pact_logs"
};
PactBuilder = new PactBuilder(pactConfig);
PactBuilder.ServiceConsumer(Common.CommonValues._consumerName)
.HasPactWith(Common.CommonValues._providerName);
MockProviderService = PactBuilder.MockService(MockServerPort);
}
}
Issue is, CreateSessionConsumer class is not assigning the static variable. And CommonFixture is accessing a unassigned variable.
This could not be handled the way I have asked here. Eventually had to implement Fixture class along with each class file, which sets the consumername and providername individually.

How to acces an instance of a class from another class?

I have the following code:
public class UnitManager
{
public string Name { get; set; }
public string Firstname { get; set; }
public UnitManager(string name, string firstname)
{
this.Name = name;
this.Firstname = firstname;
}
}
class Other
{
}
class Program
{
static void Main(string[] args)
{
var player1 = new UnitManager("p1Name", "p1FirstName");
var player2 = new UnitManager("p2Name", "p2FirstName");
}
}
So, I have created 2 objects in the Program class.
what I'd like to do is access those instances from inside the Other class to // do stuff.
For example, access player name, put a title in his name, then assess player2 and put another title.
please, keep in mind, this is just an exemple, i'm not actually planning on using this, i'm just trying to grasp the concept.
I think you can write UnitManager a property in Other class, set the UnitManager
public class Other
{
public UnitManager manager1{ get; set; }
}
or write a method the pass UnitManager instance as parameter.
public class Other
{
public void SetTitle(UnitManager m1) {
// do your logic
}
}
Thank you all, i finally understood :)
Here's how i got it working with your help:
public class UnitManager
{
public string Name { get; set; }
public string Firstname { get; set; }
public UnitManager(string name, string firstname)
{
this.Name = name;
this.Firstname = firstname;
}
}
class Other
{
public static void AddTitle(UnitManager myUnit)
{
var titlePlusFullName = ("The Legendary" + " " + myUnit.Name + " " + myUnit.Firstname);
myUnit.Name = titlePlusFullName;
}
}
class Program
{
static void Main(string[] args)
{
var player1 = new UnitManager("john", "smith");
var player2 = new UnitManager("jen", "doe");
Other oT = new Other();
Other.AddTitle(player1);
Console.WriteLine("Player 1 name: " + player1.Name);
}
}
it displays full name + title.
I think you might want something like this:
public class UnitManager
{
public string Name { get; set; }
public string Firstname { get; set; }
public UnitManager(string name, string firstname)
{
this.Name = name;
this.Firstname = firstname;
}
}
public class Other
{
public void doSomething(UnitManager myUnit) {
//do something with each unit manager
}
}
public class Program
{
static void Main(string[] args)
{
//create an object of type UnitManager and place it into variable player1
var player1 = new UnitManager("p1Name", "p1FirstName");
//create an object of type UnitManager and place it into variable player2
var player2 = new UnitManager("p2Name", "p2FirstName");
//create an instance of the class Other
Other ot = new Other();
//call the method within the instantiated class ot (of type Other) and
//pass it the instance of the object UnitManager with a name
//of player1
result1 = ot.doSomething(player1);
result2 = ot.doSomething(player2);
}
}
If you have exactly 2 instances (players), why not create them within UnitManager?
// sealed: since we have 2 instances only we don't want to
// inherit (and create) derived classes
public sealed class UnitManager
{
public string Name { get; set; }
public string Firstname { get; set; }
// private: since we have 2 intances only we don't want to expose the constructor
private UnitManager(string name, string firstname)
{
this.Name = name;
this.Firstname = firstname;
}
// Think over renaming these fields: say, Player and Computer
public static readonly UnitManager Player1 = new UnitManager("p1Name", "p1FirstName");
public static readonly UnitManager Player2 = new UnitManager("p2Name", "p2FirstName");
}
Then address them as UnitManager.Player1 (UnitManager.Player2) e.g.
class Program
{
static void Main(string[] args)
{
UnitManager.Player1.Name = "First Name";
UnitManager.Player2.Name = "Second Name";
...
}
}
Or even (with a help of static import):
using static MyNamepace.UnitManager;
...
class Other
{
public void DoSomething()
{
// We don't have now put it as UnitManager.Player1
string name1 = Player1.Name;
...
}
}

Find a property on an object instance by it's attribute value

I have a DTO that looks like this:
public class MyDto
{
[MyAttribute("attribute1")]
public string Property1 {get;set;}
[MyAttribute("attribute2")]
public string Property2 {get;set;}
}
If I have the string "attribute1", how do I use that to get to the value of Property1 in an instance of MyDto?
Use Reflection. Unfortunately, there's no way to obtain the property from an attribute: you have to iterate through each property and check its attribute.
Not the most robust code, but try this:
public class MyAttributeAttribute : Attribute
{
public MyAttributeAttribute(string value)
{
Value=value;
}
public string Value { get; private set; }
}
public class MyDto
{
[MyAttribute("attribute1")]
public string Property1 { get; set; }
[MyAttribute("attribute2")]
public string Property2 { get; set; }
}
class Program
{
static void Main(string[] args)
{
MyDto dto=new MyDto() { Property1="Value1", Property2="Value2" };
string value=GetValueOf<string>(dto, "attribute1");
// value = "Value1"
}
public static T GetValueOf<T>(MyDto dto, string description)
{
if(string.IsNullOrEmpty(description))
{
throw new InvalidOperationException();
}
var props=typeof(MyDto).GetProperties().ToArray();
foreach(var prop in props)
{
var atts=prop.GetCustomAttributes(false);
foreach(var att in atts)
{
if(att is MyAttributeAttribute)
{
string value=(att as MyAttributeAttribute).Value;
if(description.Equals(value))
{
return (T)prop.GetValue(dto, null);
}
}
}
}
return default(T);
}
}

C# Avoid Multiple SWITCH Statements .net

Please excuse bursts of stupidity as I learn the intricacies of C# / .NET
Say I have three classes with multiple static properties (more than three but for arguments sake..)
CLASS FOO
public static A
{
get / set A;
}
public static B
{
get / set B;
}
public static C
{
get / set C;
}
CLASS BAR
{
get / set A;
}
public static B
{
get / set B;
}
public static C
{
get / set C;
}
CLASS YOO
{
get / set A;
}
public static B
{
get / set B;
}
public static C
{
get / set C;
}
And from another class I need to update one or several static properties in each class multiple times... How do I keep from writing multiple SWITCH statments like this...
public void updateVarx(string class, string varx)
{
string y = 'class'
SWITCH (y)
{
case FOO:
FOO.A = Varx;
break;
case BAR:
BAR.A = Varx;
break;
case YOO:
YOO.A = Varx;
break;
}
}
And then another one when I want to update B varY:
public void updateVary(string class, string vary)
{
string y = 'class'
SWITCH (y)
{
case FOO:
FOO.B = Vary;
break;
case BAR:
BAR.B = Vary;
break;
case YOO:
YOO.B = Vary;
break;
}
}
Since you are learning .net/c#, I guess i should warn you, using static properties is probably not the way to go in object oriented programming.
Static is global state and is dangerous. If you end up using multi-threaded code, you have to be super careful. If you need only one instance, just instantiate one, but don't go creating static properties on a class, unless you have a pretty good reason to add them (And I can't think of any right now).
In fact, in well designed, object oriented code you sould probably not have many if, switch, getters or setters either.
Let's say you need different behaviors on your classes, you can do it this way.
Interface ISecurity {
void UpdateVarX(int value);
void UpdateVarY(int value);
int GetValueX();
int GetValueX();
}
class Foo:ISecurity {
// Implement methods of the interface
}
class Bar:ISecurity {
// Implement methods of the interface
}
class Yoo:ISecurity {
// Implement methods of the interface
}
// This class is the class that uses your other classes
class Consumer
{
private ISecurity sec;
public Consumer(ISecurity sec) {
sec.UpdateVarX(25);
}
}
Or if as in your example, all your static classes have the same properties:
public class Settings {
public int A {get; set;}
public int B {get; set;}
public int C {get; set;}
}
public class NeedsToUseOtherClass {
public NeedsToUseOtherClass() {
Settings foo = new Settings();
Settings bar = new Settings();
Settings yoo = new Settings();
foo.setA(25);
}
}
Maybe I am not understanding the problem but if all your classes have the same exact properties then you can just pass the object (FOO, BAR, or YOO) into UpdateVarx or UpdateVary methods and just implement an interface? Something along these lines:
public class FOO : IHasStatus
{
public A
{
get / set A;
}
public B
{
get / set B;
}
public C
{
get / set C;
}
}
public void updateVarx(IHasStatus someObject, string varx)
{
someObject.A = varx;
}
public void updateVary(IHasStatus someObject, string vary)
{
someObject.B = vary;
}
If you don't need the concrete classes, you can abstract out the logic like so:
public class Status {
public string A {
get; set;
}
public string B {
get; set;
}
public string C {
get; set;
}
}
public static class StatusManager {
private static Dictionary<string, Status> statusMap = new Dictionary<string,Status>();
public static Status GetStatus(string name) {
Status status;
if (!statusMap.TryGetValue(name, out status))
statusMap[name] = status = new Status();
return status;
}
public static void SetStatus(string name, Status status) {
statusMap[name] = status;
}
public static void UpdateVarx(string name, string varx) {
GetStatus(name).A = varx;
}
// ...
}
If you are a fan of the javascript way of solving multiple switch cases like this
you can always wrap up the switch handlers as Actions and toss them in a Dictionary.
For example : (Source obtained from here)
public class SwitchCase : Dictionary<string,Action>
{
public void Eval(string key)
{
if (this.ContainsKey(key))
this[key]();
else
this["default"]();
}
}
//Now, somewhere else
var mySwitch = new SwitchCase
{
{ "case1", ()=>Console.WriteLine("Case1 is executed") },
{ "case2", ()=>Console.WriteLine("Case2 is executed") },
{ "case3", ()=>Console.WriteLine("Case3 is executed") },
{ "case4", ()=>Console.WriteLine("Case4 is executed") },
{ "default",()=>Console.WriteLine("Default is executed") },
};
mySwitch.Eval(c);
Below code uses all kinds of hacks, not really recommended in production code unless you have a very good reason.
using System;
using System.Linq;
namespace ConsoleApplication1
{
static class Program
{
private static void SetStaticProperty(string className, string propName, string varx)
{
//This sucks, I couldnt find the namespace with easily through reflection :(
string NAMESPACE = "ConsoleApplication1";
Type t = Type.GetType(NAMESPACE + "." + className);
t.GetProperties().Where(p => p.Name == propName).First().SetValue(null, varx, null);
}
public static void updateVarx(string className, string varx)
{
SetStaticProperty(className, "A", varx);
}
public static void updateVary(string className, string vary)
{
SetStaticProperty(className, "B", vary);
}
static void Main(string[] args)
{
updateVarx("Foo", "FooAstring");
updateVarx("Bar", "BarAstring");
updateVarx("Yod", "YodAstring");
updateVary("Foo", "FooBstring");
updateVary("Bar", "BarBstring");
updateVary("Yod", "YodBstring");
Console.WriteLine(Foo.A);
Console.WriteLine(Foo.B);
Console.WriteLine(Bar.A);
Console.WriteLine(Bar.B);
Console.WriteLine(Yod.A);
Console.WriteLine(Yod.B);
Console.ReadLine();
}
}
class Foo
{
public static string A { get; set; }
public static string B { get; set; }
public static string C { get; set; }
}
class Bar
{
public static string A { get; set; }
public static string B { get; set; }
public static string C { get; set; }
}
class Yod
{
public static string A { get; set; }
public static string B { get; set; }
public static string C { get; set; }
}
}
You can use dictionary as configuration and remove the switch statement
Create a dictionary and add append data as below for mapping
//Have dictionary setted up
Dictionary<string, dynamic> m_Dictionary = new Dictionary<string, dynamic>();
m_xmlDictionary.Add("classA",FOO);
m_xmlDictionary.Add("classB",BAR);
m_xmlDictionary.Add("classC",BAR);
//Have dictionary setted up
//change the function as below
public void updatevarx(string class, string varx)
{
m_Dictionary[class].A=varx // Replaced switch statement
}
//while calling use
updatevarx("classC","abc!");// This will assign BAR.A with abc!

Attribute class not calling constructor

I have created an Attribute, call MyAttribute, which is performing some security and for some reason the Constructor is not being fired, any reason why?
public class Driver
{
// Entry point of the program
public static void Main(string[] Args)
{
Console.WriteLine(SayHello1("Hello to Me 1"));
Console.WriteLine(SayHello2("Hello to Me 2"));
Console.ReadLine();
}
[MyAttribute("hello")]
public static string SayHello1(string str)
{
return str;
}
[MyAttribute("Wrong Key, should fail")]
public static string SayHello2(string str)
{
return str;
}
}
[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{
public MyAttribute(string VRegKey)
{
if (VRegKey == "hello")
{
Console.WriteLine("Aha! You're Registered");
}
else
{
throw new Exception("Oho! You're not Registered");
};
}
}
Attributes are applied at compile time, and the constructors used only to fill in the properties. Attributes are metadata, and can only be examined at runtime.
In fact, Attributes should not contain any behavior at all.
Actually it fails, but only if you are trying to get attribute properties. Here is an example that fails:
using System;
public class Driver
{
// Entry point of the program
public static void Main(string[] Args)
{
Console.WriteLine(SayHello1("Hello to Me 1"));
Console.WriteLine(SayHello2("Hello to Me 2"));
Func<string, string> action1 = SayHello1;
Func<string, string> action2 = SayHello2;
MyAttribute myAttribute1 = (MyAttribute)Attribute.GetCustomAttribute(action1.Method, typeof(MyAttribute));
MyAttribute myAttribute2 = (MyAttribute)Attribute.GetCustomAttribute(action2.Method, typeof(MyAttribute));
Console.ReadLine();
}
[MyAttribute("hello")]
public static string SayHello1(string str)
{
return str;
}
[MyAttribute("Wrong Key, should fail")]
public static string SayHello2(string str)
{
return str;
}
}
[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{
public string MyProperty
{
get; set;
}
public string MyProperty2
{
get;
set;
}
public MyAttribute(string VRegKey)
{
MyProperty = VRegKey;
if (VRegKey == "hello")
{
Console.WriteLine("Aha! You're Registered");
}
else
{
throw new Exception("Oho! You're not Registered");
};
MyProperty2 = VRegKey;
}
}

Categories

Resources