I wanna access my passed dynamic class property in generic class. How can i do?
My class property is here.
public class Test
{
[DataMember]
public string Body { get; set; }
[DataMember]
public string Header { get; set; }
}
I sent 'Test' class to Class1.
public class Class1
{
public static T Fill<T>(T myClass)
{
//how can i access Test class property in here?
myClass.Header ????
return obj;
}
}
I passed class to generic method as follows.
var x = Class1.Fill(new Test());
Please help. Thank you.
If you really need dynamic and sure there's a Header string property then you can do this:
public class Class1
{
public static dynamic Fill(dynamic myClass)
{
myClass.Header = "222";
...
...
return myClass; // or whatever
}
}
But, if you ended up with that, i would recommend that you review your desgin.
If the generic class is always derived from Test you can use a type constraint to have access to the properties of the class:
public static T Fill<T>(T myClass) where T: Test
{
myClass.Header //Will work
return obj;
}
If the class is not derived from test, you will have to use reflection to have access to the property. Using simple reflection you can do something like :
public static T Fill<T>(T myClass) where T: Test
{
typeof(T).GetProperty("Header").GetValue(myClass); // Get the value
return obj;
}
Related
At first, I have a parent class like:
public class Father {
// skip ...
}
And these are two classes that inherit from Father. But Method_A only belongs to Child_A instead of Child_B.
public class Child_A : Father {
// skip ...
public void Method_A { ... }
}
public class Child_B : Father {
// skip ...
}
Finally, I try to create a variable can be assigned dynamically to
public class MyClass {
public Father dynamicObject;
public void MyMethod {
dynamicObject = new Child_A(); // Sometimes will be `Child_B`.
if (...) { // only `Child_A` can pass, I promise
dynamicObject.Method_A(); // Error here.
}
}
The error like below:
Type 'Father' does not contain a definition for 'Method_A' and no extension method 'Method_A' of type 'Father' could be found. Are you missing an assembly reference?
I had tried var type for dynamicObject, but we must set the var type in local scope.
public class MyClass {
public var dynamicObject; // It's not allow.
// ...
}
Use a cast to check the type of the dynamicObject:
Child_A childA = dynamicObject as Child_A;
if (childA != null)
{
childA.Method_A();
}
or with C# 6 and Null-conditional operator:
Child_A childA = dynamicObject as Child_A;
childA?.Method_A();
also is with an explicit (Child_A) cast could be used but I prefer the first approach.
if (dynamicObject is Child_A) {
((Child_A)dynamicObject).Method_A();
}
with C#7 and Pattern Matching like #Zbigniew suggested:
if (dynamicObject is Child_A child) {
child.Method_A();
}
Try to replace
dynamicObject.Method_A();
by
((Child_A)dynamicObject).Method_A();
i thing, It makes more sense to use the Method_A over the interface. while number of methods and classes increases, it will be easier to manage
public class Father { }
public class Child_A : Father, IMethodOwner { public void Method_A() { }}
public class Child_B : Father{ }
public interface IMethodOwner { void Method_A(); }
public class MyClass
{
public Father dynamicObject;
public void MyMethod() {
var obj = dynamicObject as IMethodOwner;
if(obj != null)
obj.Method_A();
}
}
I have a generic class that I want to cast to a dynamic generic, but I get a Cannot convert type MyGeneric1<MyTypedClass1> to MyGeneric1<dynamic> error message. Is this kind of cast to dynamic possible, and if so then please explain.
Here is where I try to cast a typed MyGeneric1 generic class into a dynamic MyGeneric1.
public static class Extensions
{
public static MyGeneric1<dynamic> ToDynamic(this MyGeneric1<MyTypedClass1> myObj1)
{
return (MyGeneric1<dynamic>)myObj1;
}
}
The MyGeneric1 class is defined like so:
public class MyGeneric1<T> : DynamicObject { // Code here ... }
The MyTypedClass1 class is defined like so:
public class MyTypedClass1: DynamicObject { // Code here ... }
MyTypedClass1 is assignable to dynamic, as it inherits from it. But you cannot simply cast generic classes, when they have different generic arguments, even when arguments themselves are valid for assigning (as MyTypedClass1 and dynamic ).
But, you can create new instance with proper generic type and assign value for it:
public class MyTypedClass1 : DynamicObject
{
public string SomeProperty { get; set; }
}
public class MyGeneric<T> : DynamicObject
{
// just some property to get the idea
public T Value { get; set; }
}
public static class MyGenericExtensions
{
public static MyGeneric<dynamic> ConveretGeneric(this MyGeneric<MyTypedClass1> argument)
{
return new MyGeneric<dynamic>()
{
// here you need to assign all needed properties
Value = argument.Value
};
}
}
I have an interface:
interface IInterface
{
string Name { get; }
}
that is implemented by an generic abstract class:
public class BInterface<T> : IInterface
{
static BInterface()
{
// Or anything that would be implementation class specific
Name = typeof(BInterface<>).GetType().Name;
}
public static string Name { get; private set; }
string IInterface.Name { get { return Name; } }
}
Which is in turn implemented in a concrete class:
public class CInterface : BInterface<int>
{
}
I know how to get the references to the concrete classes via 'type.IsAssignableFrom', '!type.IsInterface' and '!type.IsAbstract', but that is as far as I have managed.
I need to get, via Reflection, the VALUE of the static Name property for any of the concrete classes. However, for the life of my poor brain, I cannot figure the code to accomplish this. Any hints would be great.
EDIT (In clarification):
I am aware that the static property needs to read from the base class. However....
The static field will contain the base name of the concrete class --> derived via reflection in the static constructor of the base class. This works (and I know how to accomplish it) as we do it all over the place.
I this case, I am attempting to build a factory class that needs to know this static field, and needs to get to it via Reflection due to the some (other) requirements of the factory implementation.
EDIT (again) Expanded code:
Here is a nearly complete, if useless, example of what I am attempting to accomplish.
public interface IInterface
{
string Name { get; }
object Value { get; set; }
}
public class BInterface<T> : IInterface
{
static BInterface()
{
// Or anything that would be implementation class specific
Name = typeof(BInterface<>).GetType().Name; // Should be CInterface, DInterface depending on which class it is called from.
}
string IInterface.Name { get { return Name; } }
object IInterface.Value { get { return Value; } set { Value = (T)value; } }
public static string Name { get; private set; }
public T Value { get; set; }
}
public class CInterface : BInterface<int>
{
}
public class DInterface : BInterface<double>
{
}
public static class InterfaceFactory
{
private readonly static IDictionary<string, Type> InterfaceClasses;
static InterfaceFactory()
{
InterfaceClasses = new Dictionary<string, Type>();
var assembly = Assembly.GetExecutingAssembly();
var interfaceTypes = assembly.GetTypes()
.Where( type => type.IsAssignableFrom(typeof (IInterface))
&& !type.IsInterface
&& !type.IsAbstract);
foreach (var type in interfaceTypes)
{
// Get name somehow
var name = "...";
InterfaceClasses.Add(name, type);
}
}
public static IInterface Create(string key, object value, params object[] parameters)
{
if (InterfaceClasses.ContainsKey(key))
{
var instance = (IInterface) Activator.CreateInstance(InterfaceClasses[key], parameters);
instance.Value = value;
return instance;
}
return null;
}
}
The part in the static constructor of the IntefaceFactory inside the foreach loop is what I am attempting to solve. Hopefully, this is clearer.
This is how to get static property of concrete class from the instance:
var staticProperty = instance.GetType()
.GetProperty("<PropertyName>", BindingFlags.Public | BindingFlags.Static);
var value = staticProperty.GetValue(instance, null);
static members don't work the way you are thinking. They belong to the base class and thus what you are attempting is not possible with a static inherited member.
If I have the following code:
public abstract BaseClass
{
public void SendName(<Take in an interface>)
{ // Do stuff }
}
public class Derived : BaseClass, IMyProperties
{
public string IMyProperties.Name { get; set; }
public void Derived()
{
IProperties.Name = "Dave";
}
public void SendNameToBase
{
base.SendName(//I want to send IProperties);
}
}
How do I send IProperties to the base class?
Your base class's method should be defined like such:
public void SendName(IProperties props)
{ // Do stuff }
You call this method from the child class like this: (assuming you want to pass the current instance of the your child class, since it implements IProperties)
base.SendName(this);
Note: I'm also assuming that IMyProperties == IProperties in your code example.
well since you explicitly setup the interface, you would have to do
base.SendName((IMyProperties)this);
What exactly do you mean by sending an interface?
If you want to pass the type statically, you can use a generic (i.e. templated) method:
public void SendName<T>(T properties)
where T : IProperties // types passed in must derive from IProperties
{
var name = properties.Name;
// ...
}
//...
// Usage:
base.SendName<IProperties>(this);
If you want to send the type at runtime, you can pass around Type objects:
public void SendName(Type type)
{ /* Do stuff */ }
//...
// Usage:
base.SendName(typeof(IProperties));
I am not sure what you are trying to accomplish, but maybe if you declared the variable in the base clase you would be able to access IProperties in both functions
public abstract BaseClass
{
public string IMyProperties.Name { get; set; }
public void SendName(<Take in an interface>)
{ // Do stuff }
}
I have the following situation:
public interface IStuffer
{
public string Foo { get; }
}
public class BaseClass
{
public static string Foo { get { ... } }
}
public class MyClass : BaseClass, IStuffer
{
}
This won't build because MyClass needs a Foo member. How can I use BaseClass's Foo implementation to satisfy MyClass's requirement for Foo?
It's because Foo is a static member of the BaseClass. Just take away the static keyword!
public class BaseClass
{
public string Foo { get { ... } }
}
Edit: Else if you really want it to stay static, you could use an explicit implementation
public class MyClass : BaseClass, IStuffer
{
string IStuffer.Foo { get { return BaseClass.Foo; } }
}
The problem is that your interface expects a NON-static "string Foo", if you make Foo Non-Static in BaseClass then it will satisfy your Interface :)
Good Luck
Interfaces cannot support static properties or methods. If you have an interface, all methods of that interface must be instance rather than class scope.
In two ways:
1. Rename Foo to something else and add a method Foo like this:
public class BaseClass
{
public static string FormerlyCalledFoo { get { ... } }
public string Foo { get { ... } }
}
2. If you absolutely must have a static Foo property then you can implement the IStuffer interface as an explicit interface implementation like this:
public class BaseClass : IStuffer
{
public static string Foo { get { ... } }
string IStuffer.Foo { get { ... } }
}
If using the latter method, then you have to be aware that you have to cast instances of BaseClass to IStuffer to access the IStuffer.Foo property