C# Reflection Getting static property of concrete class from Interface - c#

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.

Related

Factory that should return different types based on input param

I have type based on which I need to create different objects. The one specific thing - all that object has some common part.
So I thought to have some base class for them. And in each separate class add only specific properties.
class BaseClass {
public int Prop1 {get;set;}
public string Prop2 {get;set;}
}
class MyClass1 : BaseClass {
public int PropMyClass1 {get;set;}
}
class MyClass2 : BaseClass {
public string PropMyClass2 {get;set;}
}
I thought about create factories:
interface ICreator<T>{
bool CanHanlde(string type);
T Create();
}
class Creator1: ICreator<MyClass1>
{
bool CanHandle(string type) {return "type1" == type;}
MyClass1 Create();
}
class Creator2: ICreator<MyClass2>
{
bool CanHandle(string type) {return "type2" == type;}
MyClass2 Create();
}
And now I would like to create some factory that will return concreate class based on type.
Problem - I don't know how to pass type into generic. From where I need to get type?
I can register all types for ICreator and inject it with DI. Select the one which return true in CanHandle method. But don't know how to get type for generic.
I can register all types for ICreator and inject it with DI. Select the one which return true in CanHandle method. But don't know how to get type for generic.
Really bizarre question. My understanding is you want to iterate on the available types, call CanHandle and return that type if the method returns true. This will require instantiating an instance of each type. Probably this is not what you want, lots of ways for this to go wrong and can't even get compile time checking. But here's how to do this.
First, use reflection to get available types. Then filter the types to the ones that implement the interface. Then instantiate the class. Call "CanHandle" on the class (which the interface says will exist), and if true, you have found your class.
You can separate your classes by assembly/namespace for easier time finding particular classes.
using SomeNamespace;
using System.Reflection;
namespace SomeNamespace
{
public class MyClass1 { public int Id { get; set; } }
public class MyClass2 { public int Id { get; set; } }
public interface ICreator<T>
{
bool CanHandle(string type);
T Create();
}
public class Creator1 : ICreator<MyClass1>
{
public Creator1() { }
public bool CanHandle(string type) { return "type1" == type; }
public MyClass1 Create() { return new MyClass1(); }
}
public class Creator2 : ICreator<MyClass2>
{
public Creator2() { }
public bool CanHandle(string type) { return "type2" == type; }
public MyClass2 Create() { return new MyClass2(); }
}
}
namespace SomeOtherNamespace
{
internal class Program
{
static void Main(string[] args)
{
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && t.Namespace == "SomeNamespace")
.ToList();
var typeNameToTest = "type2";
foreach (var type in types)
{
if (type.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICreator<>)))
{
// Requires resolving to a matching constructor, the default constructor (no arguments) is implemented above.
var newInstance = Activator.CreateInstance(type);
// pick any implementation for nameof...
// Probably this can fail if `CanHandle` doesn't exist.
var canHandleMethod = type.GetMethod(nameof(Creator1.CanHandle));
// This can fail if the signature for `CanHandle` ever changes.
bool canHandleResult = (bool)canHandleMethod.Invoke(newInstance, new object[] { typeNameToTest });
if (canHandleResult)
{
Console.WriteLine($"Found class that can handle type \"{typeNameToTest}\": {newInstance.GetType().FullName}");
break; // or return newInstance
}
}
}
}
}
}
Console output:
Found class that can handle type "type2": SomeNamespace.Creator2
See also How to determine if a type implements a specific generic interface type and How can I get all classes within a namespace?.
This would be an easy solution and I hope it helps you:
The class Creator should be instantiated only once and with the list of types it could handle.
public interface ICreator<T>{
bool CanHanlde(string type);
T Create(string type);
}
public class Creator: ICreator<BaseClass>
{
List<string> handleTypes;
public Creator(List<string> supportedTypes)
{
this.handleTypes= supportedTypes;
}
public bool CanHandle(string type)
{
return this.handleTypes?.Contains(type);
}
public BaseClass Create(string type)
{
switch(type)
{
case "type1": return new MyClass1();
case "type2": return new MyClass2();
}
return null;
}
Since you are querying the types as string from a database, you have a dynamic scenario. I.e., you know the type only at runtime.
Generic types are always resolved at compile time. Therefore, they are not helpful here. Specifically it does not help much to return the concrete type (MyClass1, MyClass2) from the factory, as you cannot type the variable at runtime. You must use BaseClass at compile time.
// You don't know whether this will return MyClass1 or MyClass2 at runtime
BaseType result = creator.Create(typeStringFromDb);
You can use a type pattern in a switch statement to access the specialized properties:
BaseType result = creator.Create(typeStringFromDb);
switch (result) {
case MyClass1 obj1:
int prop1 = obj1.PropMyClass1;
...
break;
case MyClass2 obj2:
string prop2 = obj2.PropMyClass2;
...
break;
default:
break;
}
You can still use a generic interface to make it usable with other base types, but you will have to initialize it with a base type.
interface ICreator<TBase>{
string Handles { get; }
TBase Create();
}
Instead of having a method CanHandle returning a Boolean, I suggest returning the handled type in a string property. This allows you to store the factories in a dictionary and to use this string as key.
I'll do this in a static class with a static constructor to setup the dictionary.
// Given the classes
class Creator1 : ICreator<BaseClass>
{
public string Handles => "type1";
public BaseClass Create() => new MyClass1();
}
class Creator2 : ICreator<BaseClass>
{
public string Handles => "type2";
public BaseClass Create() => new MyClass2();
}
// The static creator
static class Creator
{
private static readonly Dictionary<string, ICreator<BaseClass>> _creators = new();
static Creator()
{
ICreator<BaseClass> creator1 = new Creator1();
ICreator<BaseClass> creator2 = new Creator2();
_creators.Add(creator1.Handles, creator1);
_creators.Add(creator2.Handles, creator2);
}
public static BaseClass Create(string type)
{
if (_creators.TryGetValue(type, out var creator)) {
return creator.Create();
}
return null; // Or throw exception.
}
};
Usage
BaseClass result = Creator.Create("type1");
Upate 1, return specific type
A different variant returns the specialized type but requires a switch statement (or switch expression) to handle the different types. You cannot avoid this, if you want to access the additional members of the derived classes (PropMyClass1, PropMyClass2).
We declare the interface like this. Note the out keyword. It makes the generic types covariant. This allows us add the different creators as ICreator<object> to the dictionary.
interface ICreator<out T>
{
T Create();
}
The Creator factory now uses a dictionary key of type System.Type:
static class Creator
{
private static readonly Dictionary<Type, ICreator<object>> _creators = new();
static Creator()
{
_creators.Add(typeof(MyClass1), new Creator1());
_creators.Add(typeof(MyClass2), new Creator2());
}
public static T Create<T>()
{
if (_creators.TryGetValue(typeof(T), out var creator)) {
return ((ICreator<T>)creator).Create();
}
throw new ArgumentException("Non supported type", nameof(T));
}
};
The concrete creators now return the specialied types:
class Creator1 : ICreator<MyClass1>
{
public MyClass1 Create() => new MyClass1();
}
class Creator2 : ICreator<MyClass2>
{
public MyClass2 Create() => new MyClass2();
}
Usage:
switch (typeStringFromDb) {
case "type1":
MyClass1 obj1 = Creator.Create<MyClass1>();
int prop1 = obj1.PropMyClass1;
//TODO: Do MyClass1 stuff
break;
case "type2":
MyClass2 obj2 = Creator.Create<MyClass2>();
string prop2 = obj2.PropMyClass2;
//TODO: Do MyClass2 stuff
break;
default:
break;
}
Update 2, use Polymorphism
But maybe you should tackle things differently and use Polymorphism. To do this, we must formulate the classes in a way that allows us to use the additional properties without having to know the exact class type. This way, we would always work with BaseClass.
Now, we implement the base class as abstract class having an abstract method to handle the additional properties
abstract class BaseClass
{
public int Prop1 { get; set; }
public string Prop2 { get; set; }
abstract public void DoStuffWithAdditionalProperty();
}
class MyClass1 : BaseClass
{
public int PropMyClass1 { get; set; }
public override void DoStuffWithAdditionalProperty()
{
//TODO: use PropMyClass1 here
}
}
class MyClass2 : BaseClass
{
public string PropMyClass2 { get; set; }
public override void DoStuffWithAdditionalProperty()
{
//TODO: use PropMyClass2 here
}
}
The creator interface is not generic anymore:
interface ICreator
{
string Handles { get; }
BaseClass Create();
}
Implementing the creators and the creator factory is now straight forward and I will not show it here.
Usage:
BaseClass result = Creator.Create("type1");
result.DoStuffWithAdditionalProperty();

Creating generic method to construct and return generic objects?

I want to create a method that will return a Response<> object and set the generic properties based on the type of the object passed in as a parameter. General code example below and additional considerations at the bottom of the post.
public class Response<T>
{
public string ResponseCode { get; get; }
public T Object { get; set;}
public List<T> Objects { get; set; }
public Response()
{
}
}
public class ChildrenResponses
{
public ChildrenResponses() // constructor
{
}
// some properties
}
public class AdultResponses
{
public AdultResponses() // constructor
{
}
// some properties
}
public Response<T> GetSpecificResponseType<T>(T genericType)
{
// ... some logic to instantiate a Response<> object using the parameter type passed into the method.
// ... some logic to set the generic properties of Response<> object based on the parameter type passed into the method.
// return object
}
I'm new to C# generics/reflection :)
Being as the Response/ChildrenResponse/AdultResponse classes existed in this code base before I began using it, I'd like to avoid changing those classes.
I've attempted multiple methods to accomplish this task, but none of them worked and providing them in this post would likely just add confusion. Instead, I provided a base method with the general idea I was working with.
An example of how I'd like to call the method:
Response<ChildrenResponses> result = GetSpecificResponseType<ChildrenResponses>("ChildrenResponses");
This method will then return the Response< ChildrenResponses > object with the Object property set to new ChildrenResponses() and Objects set to new List< ChildrenResponses >(). No properties within the ChildrenResponses need to be established - just the instantiating the object is enough.
All you need to do is restrict your generic method to require a type with a parameterless constructor. Then you should be able to do this:
public Response<T> GetSpecificResponseType<T>() where T : new()
{
return new Response<T>()
{
Object = new T(),
Objects = new List<T>()
}
}
Call like this:
Response<ChildrenResponses> result = GetSpecificResponseType<ChildrenResponses>();
I think what you are missing is an interface. It is kind of hard to tell exactly what you are trying to do, so here is the way I interpreted the question:
public class Response<T> where T: IRepsonses, new()
{
public string ResponseCode { get; set; }
public T Object { get; set; }
public List<T> Objects { get; set; }
public Response()
{
}
}
public interface IRepsonses
{
}
public class ChildrenResponses : IRepsonses
{
public ChildrenResponses() // constructor
{
}
public string ChildSays { get; set; }
// some properties
}
public class AdultResponses : IRepsonses
{
public AdultResponses() // constructor
{
}
public string AdultSays { get; set; }
// some properties
}
class Program
{
public static Response<T> GetSpecificResponseType<T>() where T: IRepsonses, new()
{
// ... some logic to instantiate a Response<> object using the parameter type passed into the method.
// ... some logic to set the generic properties of Response<> object based on the parameter type passed into the method.
// return object
T obj = new T();
return new Response<T>()
{
Object=obj,
Objects=new List<T>()
};
}
static void Main(string[] args)
{
var resp = GetSpecificResponseType<AdultResponses>();
var adult = resp.Object.AdultSays;
}
}

Static fields of derived class not initialized before they are needed in the base class

I'm trying to create a base class that can be derived from to make custom enum classes that potentially have several fields and methods. The base class keeps a list of all defined values for each enum type and a name variable for all values. The problem I'm running into is that the static fields of deriving classes are not initializing until I call on one of them directly due to the behavior of the CLR, but they need to be initialized in order to add themselves to the list of defined values of that enum type.
For example, the collection Day.Values will be empty unless I previously did something like:
Day today = Day.MONDAY;
Is there a way to ensure the static fields in Day will be initialized if I call on Day.Values even if I don't call on one of the fields first? Or, is there a better way to achieve this functionality?
public abstract class EnumBase<T> where T : EnumBase<T>
{
private static List<T> values = new List<T>();
public static ReadOnlyCollection<T> Values
{
get
{
return values.AsReadOnly();
}
}
public string name { get; private set; }
protected EnumBase(string name)
{
this.name = name;
values.Add((T)this);
}
public override string ToString()
{
return this.name;
}
}
public class Day : EnumBase<Day>
{
public static readonly Day MONDAY = new Day("monday");
public static readonly Day TUESDAY = new Day("tuesday");
//...
private Day (string name) : base (name)
{
}
}
You could solve this using reflection to inspect the derived type for relevant fields.
Further, you can perform this initialization when Values is first accessed, deferring this work until it's needed and caching the result.
Here is an example:
public abstract class EnumBase<T> where T : EnumBase<T>
{
static Lazy<List<T>> values = new Lazy<List<T>>(FindEnumMembers);
public static IEnumerable<T> Values
{
get
{
return values.Value;
}
}
static List<T> FindEnumMembers()
{
Type derivedType = typeof(T);
return derivedType.GetFields()
.Where(f => f.FieldType == derivedType)
.Select(f => (T)f.GetValue(null))
.ToList();
}
public string name { get; private set; }
protected EnumBase(string name)
{
this.name = name;
}
public override string ToString()
{
return this.name;
}
}
public class Day : EnumBase<Day>
{
public static readonly Day MONDAY = new Day("monday");
public static readonly Day TUESDAY = new Day("tuesday");
//...
private Day (string name) : base (name)
{
}
}
Access should work either way, since these are synonymous:
Day.Values
//or//
EnumBase<Day>.Values
Note again that these are synonymous, because this is the root cause of your original problem. Calling Day.Values is actually interpreted as EnumBase<Day>.Values, and thus your static members of another type Day are not initialized by this call. By using reflection in EnumBase<T> and asking for the fields of the derived type, they will be initialized (if they have not yet been) as a side-effect of calling GetValue just like they would be if you had accessed them at that point statically.
I had no time to test this, but here is an example of having each enum class as a singleton. (I hope it works....) :D
I took the static out of your base class and added it to the "Day" singleton so that different extensions of the class will not accidentally share data.
Singletons can be called from anywhere and create one instance of themselves.
ie
Day.method(); // From anywhere
Day.addEnum('Wednesday');
public abstract class EnumBase<T> where T : EnumBase<T>
{
private List<T> values = new List<T>();
public ReadOnlyCollection<T> Values
{
get
{
return values.AsReadOnly();
}
}
public string name { get; private set; }
protected EnumBase()
{
}
public string addEnum()
{
this.name = name;
values.Add((T)this);
}
public override string ToString()
{
return this.name;
}
}
using System;
public class Day : EnumBase<Day>
{
private static Day instance;
private Day() {}
public static Day Instance
{
get
{
if (instance == null)
{
instance = new Day();
}
return instance;
}
}
addEnum('monday');
addEnum('tuesday');
}

No base class problem, How to use Castle.DynamicProxy Mixin in this particular case?

I have a 3rd party badly designed library that I must use.
It has all sorts of types it works with, we'll call them SomeType1, SomeType2 etc.
None of those types share a common base class but all have a property named Value with a different return type.
All I want to do is to be able to Mixin this class so I'll be able to call someType1Instance.Value and someType2Instance.Value without caring what the concreate type it is and without caring what the return type is (I can use object).
So my code is currently:
public interface ISomeType<V>
{
V Value {get; set;}
}
public interface ISomeTypeWrapper
{
object Value { get; set; }
}
public class SomeTypeWrapper<T> : ISomeTypeWrapper
where T : ISomeType<???>
{
T someType;
public SomeTypeWrapper(T wrappedSomeType)
{
someType = wrappedSomeType
}
public object Value
{
get { return someType.Value; }
set { someType.Value = value != null ? value : default(T); }
}
}
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
The problem is that I don't know what T might be until runtime due to the fact that I get a dictionary of objects.
I can iterate the dictionary and use reflection to create a SomeWrapperType on runtime but I would like to avoid it.
How can I mixin the concreate type of SomeType to ISomeType?
How can I know what V type parameter is? (wish I had typedefs and decltype like in c++)
How can I, with the minimum of use of reflection possible Mixin those classes with the interface/base class?
You could try the Duck Typing Extensions for Windsor. It means you will need to register each of your types.
container
.Register(Component.For(typeof(SomeType1)).Duck<ISomeType>())
.Register(Component.For(typeof(SomeType2)).Duck<ISomeType>());
You could probably use linq and the register AllTypes syntax to reduce code if the names are similar.
Alternatively in the short term create a factory which can return you the objects you need, implement a concrete object for each type. No you are using the interface you can remove the factory at a later date and replace it with something else with minimal impact:
public class SomeTypeWrapperFactory
{
public ISomeType<int> CreateWrapper(SomeType1 someType1)
{
return new SomeType1Wrapper(someType1);
}
public ISomeType<string> CreateWrapper(SomeType2 someType2)
{
return new SomeType2Wrapper(someType2);
}
}
public class SomeType1Wrapper : ISomeType<int> { ... }
public class SomeType2Wrapper : ISomeType<int> { ... }
Regardless of how you implement the wrapper, be the individually or using a god like class you have the ability to change how the wrapping is done and keep the rest of your code clean.
Why SomeTypeWrapper but not SomeObjectWrapper?
public class SomeObjectWrapper : ISomeType
{
Object _someObject;
PropertyInfo _valuePropertyInfo;
public SomeObjectWrapper(Object wrappedSomeObject)
{
_someObject = wrappedSomeObject;
_valuePropertyInfo = _someObject.GetType().GetProperty("Value", System.Reflection.BindingFlags.Public);
}
public object Value
{
get { return _valuePropertyInfo.GetValue(_someObject, null); }
set { _valuePropertyInfo.SetValue(_someObject, value, null); }
}
}
Edited With .NET 3.5 using LinFu
You may use LinFu instead of Castle. However, you would be using reflection anyway, both with Castle's and with Linfu's DynamicProxy, only hidden in the guts of the libraries instead of being exposed in your code. So if your requirement to avoid the use of reflection is out of performance concerns, you wouldn't really avoid it with this solution.
In that case I would personally choose Orsol's solution.
However: here's an example with LinFu's ducktyping.
public interface ISomeType {
object Value{get; set;}
}
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
public class SomeTypeWrapperFactory
{
public static ISomeType CreateSomeTypeWrapper(object aSomeType)
{
return aSomeType.CreateDuck<ISomeType>();
}
}
class Program
{
public static void Main(string[] args)
{
var someTypes = new object[] {
new SomeType1() {Value=1},
new SomeType2() {Value="test"}
};
foreach(var o in someTypes)
{
Console.WriteLine(SomeTypeWrapperFactory.CreateSomeTypeWrapper(o).Value);
}
Console.ReadLine();
}
}
Since you don't know the type of the SomeType's until runtime, I would not use mixins, but the visitor pattern (I know this doesn't answer the question on how to use mixins for this, but I just thought I'd throw in my 2 cents).
With .NET 4 using dynamic
See Bradley Grainger's post here on using c#4's dynamic keyword to implement the visitor pattern.
In your case, reading all the "Value" properties from your dictionary of SomeType's could work like this:
public class SomeType1
{
public int Value { get; set; }
}
public class SomeType2
{
public string Value { get; set; }
}
public class SomeTypeVisitor
{
public void VisitAll(object[] someTypes)
{
foreach(var o in someTypes) {
// this should be in a try-catch block
Console.WriteLine(((dynamic) o).Value);
}
}
}
class Program
{
public static void Main(string[] args)
{
var someTypes = new object[] {
new SomeType1() {Value=1},
new SomeType2() {Value="test"}
};
var vis = new SomeTypeVisitor();
vis.VisitAll(someTypes);
}
}

Calling Generic Property In Generic Class From Interface Implemented By Generic Class

I have a generic class that has one type parameter (T). I needed to store a collection of these generic objects that are of different types, so I created an interface that the generic class implements as suggested here. There is a property in the generic class of type T that I need to access when iterating through the generic list that contains the collection of Interface objects. So far the only way I have been able to get the value is to call a method using reflection.
interface ISomeClass {
//?
}
class SomeClass<T> : ISomeClass {
T ValueINeed { get; set;}
}
class ClassThatHasListOfGenericObjects{
List<ISomeClass> _l = new List<ISomeClass>();
public AddToList<T>(T someClass) : where T : ISomeClass {
_l.Add(someClass);
}
public SomeMethod(){
foreach(ISomeClass i in _l){
i.ValueINeed; //I don't know how to access the property in the generic class
}
}
}
As I see it you have two options. The easy option is to expose the value (as an object) on the interface (and possibly its type as well). Here's how that would look:
interface ISomeClass
{
object ValueINeed { get; set; }
// Only needed if you care about static type rather than using ValueINeed.GetType()
Type TypeOfValue { get; }
}
class SomeClass<T> : ISomeClass
{
public T ValueINeed { get; set; }
public Type TypeOfValue { get { return typeof(T); } }
object ISomeClass.ValueINeed { get { return ValueINeed; } set { ValueINeed = (T)value; } }
}
This has the disadvantage that there's a bit of casting going on and you might need to invoke reflection to do certain things with the value. It has the advantage that it's easy to understand and implement.
The other alternative would be to encode an "existential type" which truly represents a SomeClass<T> for some unknown T (like a SomeClass<?> in Java). This is much more complicated and hard to follow, but avoids any casts:
interface ISomeClassUser<X>
{
X Use<T>(SomeClass<T> s);
}
interface ISomeClassUser
{
void Use<T>(SomeClass<T> s);
}
interface ISomeClass
{
X Apply<X>(ISomeClassUser<X> user);
void Apply(ISomeClassUser user);
}
class SomeClass<T> : ISomeClass
{
public T ValueINeed { get; set; }
public X Apply<X>(ISomeClassUser<X> user) { return user.Use(this); }
public void Apply(ISomeClassUser user) { user.Use(this); }
}
// Assumes you want to get a string out, use a different generic type as needed
class XmlUser : ISomeClassUser<string>
{
public string Use<T>(SomeClass<T> s)
{
string str = "";
// do your conditional formatting here, branching on T as needed
// ...
return str;
}
}
class ClassThatHasListOfGenericObjects
{
List<ISomeClass> _l = new List<ISomeClass>();
XmlUser user = new XmlUser();
public string SomeMethod()
{
string s = "";
foreach (ISomeClass i in _l)
{
s += i.Apply(user);
}
return s;
}
}
Add ValueINeed to the interface and you'll be able to call it in SomeMethod().
I think you might just need a little refactoring. Looks like you're almost there
interface ISomeClass<T> {
T ValueINeed { get; set; }
}
class SomeClass<T> : ISomeClass {
T ValueINeed { get; set;}
}
class ClassThatHasListOfGenericObjects{
List<ISomeClass> _l = new List<ISomeClass>();
public AddToList<T>(T someClass) : where T : ISomeClass {
_l.Add(someClass);
}
public SomeMethod(){
foreach(ISomeClass i in _l){
i.ValueINeed; //this will work now, since it's in the interface
}
}
}
The elements' types you are using is of ISomeClass, so if want to access a member property you need to either cast i to SomeClass or add the property deceleration to the interface
interface ISomeClass {
T ValueNeeded
{
get;
set;
}
}
Note that you still need to implement the property in SomeClass.

Categories

Resources