c# Access specific class with Enum GetName - c#

RootObject.cs
public class RootObject
{
public Class1 Class1 { get; set; }
public Class2 Class2 { get; set; }
public Class3 Class3 { get; set; }
}
Class1.cs (Class2, Class3, ....)
public class Class1
{
public string name { get; set; }
public string surname { get; set; }
}
Enum.cs
public enum Classes
{
Class1,
Class2,
Class3
}
MyFunction.cs
nItemCount = Enum.GetNames(typeof(Classes)).Length; /* equal to 3 */
for (i=0 ; i < nItemCount; i++)
{
string name = RootObject.(Enum.GetName(typeof(Classes), i)).name;
}
I want to get the name value of Class1, Class2, Class3, etc. like a method above.
I wish I could explain my problem.
I need a solution for accessing all classes in a loop with the enum value.
Can anyone please help ?

You will have to change your code to be like below. Note I have used Classes as datatype for the Property.
public class RootObject
{
public Classes ClassProp { get; set; }
}
public enum Classes
{
Class1,
Class2,
Class3
}
And then you can access the properties by using following code. You will have to instantiate the class and then access the property as they are Object level properoties and not static. Also, note that you will have to set the properties to get the appropriate enum value.
RootObject rootObj = new RootObject();
rootObj.ClassProp = Classes.Class2;
var class2 = rootObj.ClassProp;

If your classes share common members, either move those to a common base class or let the classes implement a common interface (or both).
public abstract class Person
{
public string Name { get; set; }
public string Surname { get; set; }
}
public class Customer : Person
{
public Address DeliveryAddress { get; set; }
}
public class Employee : Person
{
public string Profession { get; set; }
}
Then, instead of creating individual properties for each the classes, add them to an array and use the enum values as index:
public enum PersonType
{
Customer = 0,
Employee = 1,
Supplier = 2
}
public class RootObject
{
Person[] _persons = new Person[] {
new Customer(),
new Employee(),
new Supplier()
};
public Person[] Persons { get { return _persons; } }
}
Now you can access the persons easily with
foreach (PersonType personType in (PersonType[])Enum.GetValues(typeof(PersonType))) {
Person p = rootObject.Persons[(int)personType];
string name = p.Name;
string surname = p.Surname;
// ...
}

First, if all of your types Class1, Class2, Class3, ..., ClassWhatNot share same property definitions, it is better to move these same property definitions into a common BaseClass which the aforementioned classes will inherit from.
class BaseClass
{
public string Name { get; set;}
}
class Class1 : BaseClass
{
...
}
class Class2 : BaseClass
{
...
}
//... do the definition of Class3 in the same way
Implement the RootClass as follows (note that i changed the names a bit to make it clearer how things work):
class RootClass
{
public enum PropertyEnum
{
propClass1,
propClass2,
propClass3
}
public Class1 propClass1 { get; set; }
public Class2 propClass2 { get; set; }
public Class3 propClass3 { get; set; }
public BaseClass GetPropertyByEnum(RootClass.PropertyEnum enumValue)
{
PropertyInfo pi = typeof(RootClass).GetProperty(enumValue.ToString());
return pi.GetValue(instance, null) as BaseClass;
}
}
With the method GetPropertyByEnum you can easily do:
RootClass rootObj = ...create/get the root object
foreach(RootClass.PropertyEnum enumValue in Enum.GetValues(typeof(RootClass.PropertyEnum))
{
BaseClass b = rootObj.GetPropertyByEnum(enumValue);
if (b != null) Console.Out.WriteLine("{0}.name = {1}", enumValue.ToString(), b.Name);
}
Note, that when not using a common base class (such as BaseClass in my example), GetPropertyByName could only return references of type Object. In such a case you would need to know how to cast the returned object to the appropriate type, which would make the whole endeavour of accessing properties by enum mostly pointless...

Related

How to get members of abstract class using reflection?

I have following:
var type = typeof(ExampleClass);
public abstract class ExampleClass
{
public string Name { get; set; }
public abstract class InternalExampleClass
{
public string InternalName { get; set; }
}
}
How can I get the value of Name, InternalName?
I tried to use type.GetFields() but it doesn't return InternalName
help me, please
I can't answer all points of your question. But I can give you an idea how to start.
You don't have access to constants, but there is a workaround. First, you need an instance of your abstract class in order to use reflection. Since you can't create an object of an abstract class, you need a class which inherits it. This class contains properties set to the value of your constants.
public class InheritedReportAPI : ReportAPI
{
public string constName { get; } = ReportAPI.Name;
public string constSignatureBase { get; } = ReportAPI.SignatureBase;
public string constEventsReportsDeleted { get; } = ReportAPI.Events.ReportsDeleted;
}
Then you can use Reflection to get names and/or values of these properties.
var inheritedReportApi = new InheritedReportAPI();
var propertyList = inheritedReportApi.GetType().GetProperties();
foreach(var property in propertyList)
System.Console.WriteLine($"{property.Name}: {property.GetValue(inheritedReportApi)}");
The result:
constName: reports
constSignatureBase: /report/reports
constEventsReportsDeleted: reports_deleted

How to create factory class which will return the derived types of common interface

I have an Interface and it is implemented by many classes. Each class also has its own set of properties which are not present in interface. Now, if I want to design a factory which returns of type interface, I cannot set some of the derived class properties as they are not member of interface.
How to address this scenario?
If you have an Interface like
public interface MyInterface
{
string Name { get; }
}
and implementations like
public class MyClass : MyInterface
{
string Name { get; set; }
int Something { get; set; }
}
public class MySecondClass : MyInterface
{
string Name { get; set; }
decimal SomethingElse { get; set; }
}
you can create your class in the factory like
public class MyFactory
{
public MyInterface createMyClass()
{
return new MyClass() { Name = "foo", Something = 42 };
}
public MyInterface createMySecondClass()
{
return new MySecondClass() { Name = "bar", SomethingElse = 4.2M };
}
}
Of course this way you can't access the members you don't have declared in your interface.
var something = myFactory.createMyClass().Something;
This wouldn't work. You can only access the name property:
var name = myFactory.createMyClass().Name;
If you would want to access the special property of your class, you would have to cast your interface to the actual class:
var something = ((MyClass)myFactory.createMyClass()).Something;

Injecting derived classes

I have a problem using ValueInjecter for derived classes:
public class A
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class B : A
{
public int Age { get; set; }
}
public static void main()
{
var b = new B()
{
Id = Guid.NewGuid(),
Name = "Test!",
Age = 47
};
var a = new A();
a.InjectFrom(b);
}
Injecter does not seem to copy the properties of the derived class.
I then tried to use the Clone convention and debugged the different calls to the methods, but I could not even see calls for the properties of the derived class. Only the properties directly on class A were called.
What am I doing wrong?
Best regards,
Andreas Kroll

Get a variable from a class that inherits another

I have an arbitrary amount of classes, classThatInherits, anotherClassThatInherits, etc. that inherit classToBeInherited.
I then have a method, b, that needs to be able to access myValue from the classes that inherit classToBeInherited. How can I achieve this, without casting?
//This class will be inherited by other classes
public class classToBeInherited {
public bool isSomething { get; set; }
}
//This class with inherit 'classToBeInherited'
public class classThatInherits : classToBeInherited {
public int myValue { get; set; } //this needs to be accessable...
}
//...And so will this class
public class anotherClassThatInherits : classToBeInherited {
public int myValue { get; set; }
}
private class normalClass {
private void a() {
classThatInherits cti = new classThatInherits();
b(cti);
anotherClassThatInherits acti = new anotherClassThatInherits();
b(acti);
}
private void b(classToBeInherited c) {
//***
//get myValue from the classes that inherit classToBeInherited
//***
}
}
Move myValue to classToBeInherited:
public class classToBeInherited {
public bool isSomething { get; set; }
public abstract int myValue { get; set; }
}
Then in classThatInherits and anotherClassThatInherits use public override int myValue { get; set; } to implement that property.
Ofcorse, if myValue is needed in only some of the classes, then you can have virtual and not abstract property.
var a = c as anotherClassThatInherits;
if (a != null)
{
var myValue = a.myValue;
}
I don't know why you don't want to do casting, but it's very common to have code like above.
UPDATED
If you really don't want casting, you can use reflection (but you still need to know the type of anotherClassThatInherits)
var getter = typeof(anotherClassThatInherits).GetProperty("myValue").GetGetMethod();
var myValue = getter.Invoke(c, null);

Update the Base Class attributes when instantiate Child class C#

I want the following, is it possible in C#
public class BaseClass
{
public string Name {get;set;}
public DateTime Login {get;set;}
}
public class ChildA : BaseClass
{
public string SchoolName{get; set;}
public string ClassName{get; set;}
}
public class childB : BaseClass
{
public string StreetAdrees{get; set;}
}
Now I want that if I create an instance of any child class Name="John" and Login "2013-12-12" or from database already set its irritating to set these attribute for every class
just like that
ChildA obj=new ChildA();
obj.Name and obj.Login already have Data
Specify constructor in base class, then create constructors in child classes which inherit from base classes constuctor like below
public class ChildA : BaseClass
{
public ChildA():base(){}
public string SchoolName{get; set;}
public string ClassName{get; set;}
}
public class BaseClass
{
public BaseClass()
{
//set Data
.....
}
....
}
read more about base keyword
In the example below, children would actually point to the same instance of base
The example uses cache, but it could be anything else (session, application state, etc).
public class BaseClass
{
private string _name;
private DateTime _login;
public string Name
{
get
{
return Instance._name;
}
set
{
_name = value;
}
}
public DateTime Login
{
get
{
return Instance._login;
}
set
{
_login = value;
}
}
public static BaseClass Instance
{
get
{
// check if null, return a new instance if null etc...
return HttpContext.Current.Cache["BaseClassInstance"] as BaseClass;
}
set
{
HttpContext.Current.Cache.Insert("BaseClassInstance", value);
}
}
}
public class ChildA : BaseClass
{
public string SchoolName { get; set; }
public string ClassName { get; set; }
}
public class childB : BaseClass
{
public string StreetAdrees { get; set; }
}
testing it:
BaseClass.Instance = new BaseClass() { Login = DateTime.Now, Name = "Test" };
ChildA ch = new ChildA();
ChildA ch2 = new ChildA();
childB chb = new childB();
Response.Write(ch.Login.Millisecond);
Response.Write("<BR/>");
Response.Write(chb.Login.Millisecond);
Result:
906
906

Categories

Resources