I need class instance from string to check if it has certain Attribute.
I have tried it like this
Type type = Assembly.GetEntryAssembly().GetType("ClassName");
object entity = Activator.CreateInstance(type);
var tableAttribute = entity.GetType().GetTypeInfo().GetCustomAttribute<TableAttribute>();
but type is null ?
Entire code in TestConsoleApp:
using System;
using System.ComponentModel;
using System.Reflection;
namespace AssemblyTest
{
[Description("TestDescription")]
public class TestClass { }
//
public class Program
{
public static void Main(string[] args)
{
Type type = Assembly.GetEntryAssembly().GetType("TestClass");
if(type == null)
Console.WriteLine("Object type is NULL.");
else
Console.WriteLine("Object type has value.");
object entity = Activator.CreateInstance(type);
var tableAttribute = entity.GetType().GetTypeInfo().GetCustomAttribute<DescriptionAttribute>();
}
}
}
When specifying the name of the class you must provide a fully qualified name that includes it's namespace. So this line needs tweaked:
Type type = Assembly.GetEntryAssembly().GetType("ClassName");
If ClassName is in namespace App.Logic then the line should be:
Type type = Assembly.GetEntryAssembly().GetType("App.Logic.ClassName");
So given your updated code the line should be:
Type type = Assembly.GetEntryAssembly().GetType("AssemblyTest.TestClass");
I have tested it and it does work if a fully qualified class name is used which includes the namespace information.
Related
I came across a lot of code in our company codebase with the following structure
class Base
{
public Base (var a, var b)
{
base_a = a;
base_b = b;
}
var base_a;
var base_b;
}
class Derived:Base
{
publc Derived (var a,b,c,d): base (a,d)
{
der_c = c;
der_d = d;
}
var der_c;
var der_d;
var der_e;
}
class Ref
{
Base _ref;
public Ref( var a,b,c,d)
{
_ref = new Derived (a,b,c,d)
}
public void method( )
{
_ref.der_e = 444; // won't compile
}
}
What is the correct way to initialize der_e ? What is the advantages of having a reference of base class and using an object derived class for _ref ? Just the fact that using a base class reference can hold multiple derived class objects ? If that's the case, should all the member variables of derived class be initialized during construction itself (like this: _ref = new Derived (a,b,c,d) ). What if I want to initialize _ref.der_e later in a method ? I know I can do this (var cast_ref = _ref as Derived; cast_ref.der_e = 444) but this look doesn't seem to the best practice. What is the idea of having such a structure and what is the correct of initializing a member of a derived class object after it has been constructed ?
Those are too many questions in a single post.
What is the correct way to initialize der_e ?
For initializing der_e you will have to have Reference of Derived class as it knows about the der_e property and not Base class.
What is the advantages of having a reference of base class and using
an object derived class for _ref ?
Yes that's called Polymorphism which is the essence of Object Oriented Programming. It allows us to hold various concrete implementations without knowing about the actual implementation.
If that's the case, should all the member variables of derived class
be initialized during construction itself (like this: _ref = new
Derived (a,b,c,d) )
There is no such rule. It depends on your scenario. If the values are not meant to be changed after the creation of the object and the values are known before hand during construction of the object then they should be initialized during construction.
Again if there are various scenarios like sometimes values are known and sometimes not then there can be Overloaded Constructors, which take different arguments.
What if I want to initialize _ref.der_e later in a method ?
That is perfectly fine, it depends on what you are trying to achieve. The question is not a concrete one but an abstract one in which it is difficult to comment on what you are trying to achieve.
I know I can do this (var cast_ref = _ref as Derived; cast_ref.der_e =
444) but this look doesn't seem to the best practice.
I am sharing some Java code which is similar to C# as I am from Java background
//This class knows about Base and nothing about the Derived class
class UserOfBase{
Base ref;
//Constructor of UserOfBase gets passed an instance of Base
public UserOfBase(Base bInstance){
this.ref = bInstance;
}
//Now this class should not cast it into Derived class as that would not be a polymorphic behavior. In that case you have got your design wrong.
public void someMethod(){
Derived derivedRef = (Derived)ref; //This should not happen here
}
}
I am sharing some references which would help you with this, as I think the answer can be very long to explain.
Factory Pattern
Dependency Injection
Head First Design Patterns
Posts on SO regarding polymorphism
You can create a constructor in your derived class and map the objects or create an extension method like this:
public static class Extensions
{
public static void FillPropertiesFromBaseClass<T1, T2>(this T2 drivedClass, T1 baseClass) where T2 : T1
{
//Get the list of properties available in base class
System.Reflection.PropertyInfo[] properties = typeof(T1).GetProperties();
properties.ToList().ForEach(property =>
{
//Check whether that property is present in derived class
System.Reflection.PropertyInfo isPresent = drivedClass.GetType().GetProperty(property.Name);
if (isPresent != null && property.CanWrite)
{
//If present get the value and map it
object value = baseClass.GetType().GetProperty(property.Name).GetValue(baseClass, null);
drivedClass.GetType().GetProperty(property.Name).SetValue(drivedClass, value, null);
}
});
}
}
for example when you have to class like this:
public class Fruit {
public float Sugar { get; set; }
public int Size { get; set; }
}
public class Apple : Fruit {
public int NumberOfWorms { get; set; }
}
you can initialize derived class by this code:
//constructor
public Apple(Fruit fruit)
{
this.FillPropertiesFromBaseClass(fruit);
}
I have a class and that class 'class1' is implementing an interface interface1
I need to invoke a method in the class using the reflection.
I can't use the class name and interface name as it is because both the name will change dynamically.`
interface1 objClass = (interface1 )FacadeAdapterFactory.GetGeneralInstance("Class"+ version);
See the above code snippet. The class name and the interface name should change according to its version. I have created the instance for class by using
Activator.CreateInstance(Type.GetType("Class1"))
but i m not able to crete the same for interface
Is there any way to implement the above context.
You can't create instance of interface, just class that implements interface.
There are some ways to extract method (info) from interface.
ISample element = new Sample();
Type iType1 = typeof(ISample);
Type iType2 = element.GetType().GetInterfaces()
.Single(e => e.Name == "ISample");
Type iType3 = Assembly.GetExecutingAssembly().GetTypes()
.Single(e => e.Name == "ISample" && e.IsInterface == true);
MethodInfo method1 = iType1.GetMethod("SampleMethod");
MethodInfo method2 = iType2.GetMethod("SampleMethod");
MethodInfo method3 = iType3.GetMethod("SampleMethod");
method1.Invoke(element, null);
method2.Invoke(element, null);
method3.Invoke(element, null);
I hope it's sufficient.
I've a base presenter class:
public abstract class PresenterBase<T> where T : IView
{
//Some code
}
A concrete presenter class that implements this base:
public class RegistrationPresenter : PresenterBase<IRegistration>
{
//Some Code
}
A concrete presenter factory to return the instance of presenter which depends on a specific interface contract:
public class ProductPresenterFactory : PresenterFactoryBase
{
// Some code
public override PresenterBase<IView> GetPresenter(IView view, string name = "")
{
if (view == null && string.IsNullOrEmpty(name))
throw new ArgumentNullException();
return presenter;
}
}
I need to implement the GetPresenter method. The user will put the interface contract, for example of type IRegistration in the above case. This method should figure out the class that implements PresenterBase<IRegistration> and return an instance.
I did not write this with a compiler; I might have made a few mistakes.
You'll first need to get the type of the presenterbase, then we'll scour the assemble for the implementation, then call it's constructor. I'll make some assumptions as written in the code.
var genericType = typeof (PresenterBase<>).MakeGenericType(new[] { view.GetType() });
var allTypes = GetType().Assembly.GetTypes(); // I assume the class is in the same assembly.
var typeToImplement = allTypes.Single(t => t.IsSubclassOf(genericType)); // I assume there is only one implementation for the given type
var constructorToCall = typeToImplement.GetConstructors().First(); // I assume there is one constructor
var presenter = constructorToCall.Invoke(new object[0]); // I assume there is no parameter
Hello from C# and OOP newbie.
How can I avoid change of class on assigning derived class object to base class object in c#?
After i run code bellow i get this response
obj1 is TestingField.Two
obj2 is TestingField.Two
I expected that i will lose access to derived methods and properties (which I did) after assigning reference but I did not expect change of class in midcode :S
using System;
namespace TestingField
{
class Program
{
static void Main(string[] args)
{
One obj1 = new One();
Two obj2 = new Two();
obj1 = obj2;
Console.WriteLine("obj1 is {0}", obj1.GetType());
Console.WriteLine("obj2 is {0}", obj2.GetType());
Console.ReadLine();
}
}
class One
{
}
class Two : One
{
public void DoSomething()
{
Console.WriteLine("Did Something.");
}
}
}
While you are right, you will lose access to members declared in the derived type, the object won't suddenly change it's type or implementation. You can access only members declared on the base type, but the implementation of the derived type is used in the case of overriden members, which is the case with GetType, which is a compiler generated method which automatically overrides the base class's implementation.
Extending your example:
class One
{
public virtual void SayHello()
{
Console.WriteLine("Hello from Base");
}
}
class Two : One
{
public void DoSomething()
{
Console.WriteLine("Did Something.");
}
public override void SayHello()
{
Console.WriteLine("Hello from Derived");
}
}
Given:
One obj = new Two();
obj.SayHello(); // will return "Hello from Derived"
GetType is a virtual method gives you the dynamic type of the object.
I think you want the static type of the variable. You can't get this by calling a method on the object referenced by the variable. Instead just write typeof(TypeName), which is typeof(One) or typeof(Two) in your case.
Alternatively in your subclass you can use a new method which hides the original one instead of overriding it:
class One
{
public string MyGetType() { return "One"; }
}
class Two : One
{
public new string MyGetType() { return "Two"; }
}
class Program
{
private void Run()
{
One obj1 = new One();
Two obj2 = new Two();
obj1 = obj2;
Console.WriteLine("obj1.GetType(): " + obj1.GetType());
Console.WriteLine("obj2.GetType(): " + obj2.GetType());
Console.WriteLine("obj1.MyGetType(): " + obj1.MyGetType());
Console.WriteLine("obj2.MyGetType(): " + obj2.MyGetType());
}
}
Result:
obj1.GetType(): Two
obj2.GetType(): Two
obj1.MyGetType(): One
obj2.MyGetType(): Two
You haven't "changed class". The type of the variable obj1 is still One. You have assigned an instance of Two to this variable, which is allowed since Two inherits from One. The GetType method gives you the actual type of the object currently referenced by this variable, not the type of the declared variable itself.
I was just trying to code the following extension method:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace _4Testing
{
static class ExtensionMethods
{
public static void AssignMe(this int me, int value)
{
me = value;
}
}
}
But it is not working, i mean, can I use an extension method to alter values from extended classes? I don't want to change void return type to int, just changing extended class value. Thanks in advance
Your example uses int, which is a value type. Classes are reference types and behaves a bit differently in this case.
While you could make a method that takes another reference like AssignMe(this MyClass me, MyClass other), the method would work on a copy of the reference, so if you assign other to me it would only affect the local copy of the reference.
Also, keep in mind that extension methods are just static methods in disguise. I.e. they can only access public members of the extended types.
public sealed class Foo {
public int PublicValue;
private int PrivateValue;
}
public static class FooExtensions {
public static void Bar(this Foo f) {
f.PublicValue = 42;
// Doesn't compile as the extension method doesn't have access to Foo's internals
f.PrivateValue = 42;
}
}
// a work around for extension to a wrapping reference type is following ....
using System;
static class Program
{
static void Main(string[] args)
{
var me = new Integer { value = 5 };
int y = 2;
me.AssignMe(y);
Console.WriteLine(me); // prints 2
Console.ReadLine();
}
public static void AssignMe(this Integer me, int value)
{
me.value = value;
}
}
class Integer
{
public int value { get; set; }
public Integer()
{
value = 0;
}
public override string ToString()
{
return value.ToString();
}
}
Ramon what you really need is a ref modifier on the first (i.e. int me ) parameter of the extension method, but C# does not allow ref modifier on parameters having 'this' modifiers.
[Update]
No workaround should be possible for your particular case of an extension method for a value type. Here is the "reductio ad absurdum" that you are asking for if you are allowed to do what you want to do; consider the C# statement:
5.AssignMe(10);
... now what on earth do you think its suppose to do ? Are you trying to assign 10 to 5 ??
Operator overloading cannot help you either.
This is an old post but I ran into a similar problem trying to implement an extender for the String class.
My original code was this:
public static void Revert(this string s)
{
char[] xc = s.ToCharArray();
s = new string(xc.Reverse());
}
By using the new keyword I am creating a new object and since s is not passed by reference it will not be modified.
I changed it to the following which provides a solution to Ramon's problem:
public static string Reverse(this string s)
{
char[] xc = s.ToCharArray();
Array.Reverse(xc);
return new string(xc);
}
In which case the calling code will be:
s = s.Reverse();
To manipulate integers you can do something like:
public static int Increment(this int i)
{
return i++;
}
i = i.Increment();