This question already has answers here:
Comparing Object properties using reflection
(5 answers)
Closed 3 years ago.
I would like to know if there is a way to create a custom class out of an existing class in this manner:
original class:
public class Person
{
string name;
}
later in code:
var diffPerson = CreateDiffClass<Person>();
diffPerson.name.Value = "name";
diffPerson.name.Changed = false;
this diffPerson is not of Person type, instead it is custom created one, that for every variable in Person have one in itself so that the new variable is a tuple where T is the type of the variable.
I want it to create a system for comparing 2 instances of the same class. one old instance and one new and save the new value and if it changed
I don't really know how to describe it except showing in this example so I hope it is understandable..
I want this to be generic and work on any given class
Thanks
You can declare a generic class like this
public class CustomValue<T>
{
public T Value { get; set; }
public bool Changed { get; set; }
}
and then use it like this
public class Person
{
public CustomValue<string> Name;
}
later in code
var diffPerson = new Person();
diffPerson.Name = new CustomValue<string>();
diffPerson.Name.Value = "name";
diffPerson.Name.Changed = false;
Related
This question already has answers here:
What is difference between Init-Only and ReadOnly in C# 9?
(4 answers)
Closed 1 year ago.
I can define a class like below:
public class MyClass
{
public int Id { get; }
public MyClass(int id) => Id = id;
}
And I have to define the Id from the constructor and it will be read-only.
But if I want to use Init only setters in the C# 9.0, what does it and how can I use it?
public class MyClass
{
public int Id { get; init; }
}
Init only setters provide consistent syntax to initialize members of an object. Property initializers make it clear which value is setting which property. The downside is that those properties must be settable.
With that, you don't need to provide the value at the beginning and the constructor and you can do it afterward:
var myClass = new MyClass
{
Id = 10
}
and it will be sealed and you cannot change it anymore.
myClass.Id = 43; // not allowed
read more info
In a nutshell:
var obj = new MyClass
{
Id = 42 // totally fine
};
obj.Id = 43; // not OK, we're not initializing
Trivial in this case and not much different to using a constructor parameter, but useful in some more complex scenarios where you don't want 200 constructor parameters, but you do want it to be outwardly immutable once constructed.
This question already has answers here:
Set object property using reflection
(10 answers)
Closed 3 years ago.
In a dynamic way, I'm looking to set the .Value property of the SyncVar property of the Unit class. The following won't compile and I don't want to hardcode SynvVar<int> because it could be a number of base types <int>, <string>, <bool>, etc.
class SyncVar<T>
{
public T Value { get; set; }
}
class Unit
{
public SyncVar<int> Health { get; set; } = new SyncVar<int>();
}
class Program
{
static void Main(string[] args)
{
Unit unit = new Unit();
unit.Health.Value = 100;
var prop = unit.GetType().GetProperty("Health").GetValue(unit);
// compile error as prop object doesn't contain .Value
// I need to dynamically figure out what type was used in this generic property so I can cast to that and set it's value
prop.Value = 50;
}
}
In case of arbitrary T you can try Reflection one time more:
prop.GetType().GetProperty("Value").SetValue(prop, 50);
This question already has answers here:
When do you use the "this" keyword? [closed]
(31 answers)
Closed 3 years ago.
Noobie here, but I was wondering why and when would I need to use "this" keyword to access the Promote method in GoldenCustomer when I can already access it since GoldenCustomer is derived from the base class Customer which already has this method? Saw "this" being used in an online course but could't help but wonder.
Edit:
No my question isnt a duplicate because the other question doesnt answer when and if it is necessary to use "this" during inheritance.
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
customer.Promote();
GoldCustomer goldCustomer = new GoldCustomer();
goldCustomer.OfferVoucher();
}
}
public class GoldCustomer : Customer{
public void OfferVoucher(){
this.Promote(); //why is this used here?
}
}
public class Customer{
public int Id { get; set; }
public string Name { get; set; }
public void Promote(){
int rating = CalculateRating(excludeOrders: true);
if (rating == 0)
System.Console.WriteLine("Promoted to level 1");
else
System.Console.WriteLine("Promoted to level 2");
}
private int CalculateRating(bool excludeOrders){
return 0;
}
}
The most common uses is when a variable in a method/function has the same name as another class-level variable.
In this case, using the this keyword will tell the compiler that you're referring to the class's variable.
For example:
public class Customer
{
public string Name { get; set; }
Public Customer (string Name, string Id)
{
this.Name = Name; // "this.Name" is class's Name while "Name" is the function's parameter.
}
}
MSDN Doc for other uses and further reading
Also, a small side-note: ID should always be stored as a string since int has the maximum value of 2147483648, and ID's are treated as a string anyway (you never use math-related functions on it like Id++ or Id = Id * 2 for example).
I'm obviously referring to state-issued IDs like "6480255197" and not "1", "2" and so on.
This question already has answers here:
How to get a property value using reflection
(2 answers)
C# Reflection - Get field values from a simple class
(3 answers)
how to get both fields and properties in single call via reflection?
(6 answers)
Closed 3 years ago.
What I'm trying to do is have a class that I can inherit from and be able to track changes to properties.
I have this base class called TrackedEntity.
I then create another class TestEntity that inherits from TrackedEntity.
On my TestEntity class I have marked one of my fields with an attribute that I called CompareValues.
TrackedEntity
public class TrackedEntity {
public void GetCompareValues<T> () {
var type = typeof (T);
var properties = type.GetProperties ();
foreach (var property in properties) {
var attribute = (CompareValues[]) property.GetCustomAttributes
(typeof(CompareValues), false);
var hasAttribute = Attribute.IsDefined (property, typeof
(CompareValues));
}
}
}
TestEntity
public class TestEntity : TrackedEntity
{
public int one { get; set; }
[CompareValues]
public int two { get; set; }
public int three { get; set; }
}
CompareValues attribute:
[AttributeUsage ( AttributeTargets.Property |
AttributeTargets.Field,
Inherited = true)]
public class CompareValues : Attribute {
public CompareValues () { }
}
I can then do this
var test = new TestEntity ();
test.GetCompareValues<TestEntity> ();
In my GetCompareValues method I can find which fields in TestEntity use my CompareValues attribute.
I am trying to find a way to access the value of the fields that have the CompareValues attribute so that I can track the changes and log information about it.
If there is any other way to get this done by using another method please let me know.
Thank you.
You´re almost there. All you need to do is to get the properties value on the current instance - the instance on which you´ve called the method:
if(hasAttribute)
{
var value = property.GetValue(this, null);
}
Apart from this you won´t need generics here. Just use this:
var type = this.GetType();
which returns TestEntity in case of the instance being of your derived type.
This question already has answers here:
get name of a variable or parameter [duplicate]
(3 answers)
Closed 6 years ago.
How to get variable name of this?
var thename = new myclass();
Whereas I want the variable name "thename" inside myclass instance?
What do you expect in the following scenario?
var theName = new MyClass();
var otherName = theName;
someList.Add(otherName);
The name(s) you're after don't belong to the instance but to the variables referencing it.
There are now three references pointing to the same instance. Two have distinct names, the third does not really have a name.
Inside a MyClass object, you can't know who's pointing at you. Heap objects themselves are always anonymous.
public class myclass()
{
public string VariableName { get; set; }
}
var theName = new myclass();
theName.VariableName = nameof(theName);
Instantiating the variable like this, it doesn't exist to have a name before you create the object. If you want to force every instance to populate that variable, then you can do something like this, but your code will be a little more verbose:
public class myclass()
{
public myclass(string variableName)
{
if (string.IsNullOrWhitespace(variableName)
{
throw new ArgumentNullException(nameof(variableName);
}
VariableName = variableName;
}
public string VariableName { get; private set; }
}
myclass theName;
theName = new myclass(nameof(myclass));
Of course, there's no guarantee that someone isn't passing in a different string.