No static in generic. But how to achieve this? - c#

Please check the following section of code (Simplified version)
my concern is in the ReadPath class where I need to call the GetPath() of the type i am using. How can I achieve this?
public interface IPath
{
string GetPath();
}
public class classA: IPath
{
string GetPath()
{
return "C:\";
}
}
public class classB: IPath
{
string GetPath()
{
return "D:\";
}
}
public class ReadPath<T> where T : IPath
{
public List<T> ReadType()
{
// How to call GetPath() associated with the context type.
}
}

public interface IPath
{
string GetPath();
}
public class classA : IPath
{
public string GetPath()
{
return #"C:\";
}
}
public class classB : IPath
{
public string GetPath()
{
return #"D:\";
}
}
public class ReadPath<T> where T : IPath, new()
{
private IPath iPath;
public List<T> ReadType()
{
iPath = new T();
iPath.GetPath();
//return some list of type T
}
}

Interfaces are instance based. So if you want to do that, pass in an instance and work with that.
However, there is a concept that is type-based: attributes:
[TypePath(#"C:\")]
public class classA
{
}
[TypePath(#"D:\")]
public class classB
{
}
public class ReadPath<T>
{
public static List<T> ReadType()
{
var attrib = (TypePathAttribute)Attribute.GetCustomAttribute(
typeof(T), typeof(TypePathAttribute));
var path = attrib.Path;
...
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct
| AttributeTargets.Interface | AttributeTargets.Enum,
AllowMultiple = false, Inherited = false)]
public class TypePathAttribute : Attribute
{
public string Path { get; private set; }
public TypePathAttribute(string path) { Path = path; }
}

Another solution is instance member, but you should change a declaration of generic a little bit:
public class ReadPath<T> where T : IPath, new() //default ctor presence
{
T mem = new T();
public string ReadType()
{
return mem.GetPath();
}
}
Not that I changed returned type as it's not clear how you gonna fit return type string with List<T>

You are confusing between few different aspects of .net/c# programing.
Static methods (which you dont even have here) cannot be defined via interfaces, so if you're interested in using static methods, the interface wotn help you, and you could execute such method in a generic way only by means of reflection.
Your code is abit not clear, hard to understand why your readtype method returns a list, and how are you supposed to fill up this list.

Related

Get trait in subclass

I'm sorry if this is poorly worded or if this has been asked before but I couldn't seem to find anything related to this and I'm quite tired.
Alright, so what I'm trying to do is get the value of of my trait in a subclass for situations where I need to reference an instance of a subclass but I don't have the information about what trait it will be using. This is easier for me to explain in code so here's what I'm trying to do.
public class TraitUser<T>
{
public void DoThingWithT(T thing)
{
thing.ToString();
}
}
public class TraitInspector
{
public void DoThing()
{
// This is where I run into my issue,
// I need to be able to get the trait that
// an instance of the TraitUser class is using to continue.
TraitUser<> tUser = GetRandomTraitUser()/*Imagine this returns an instance of TraitUser with a random trait, this is where my issue comes in.*/;
}
}
If I understand youright, you need get information about generic type T in TraitUser instance in TrairInspector.
public interface IGetTraitInfo
{
Type GetTraitObjectType();
object GetTraitObject();
}
public class TraitUser<T> : IGetTraitInfo
{
private T _thing;
public void DoThingWithT(T thing)
{
_thing = thing;
}
public Type GetTraintObjectType()
{
return typeof(T);
}
public Type GetTraitObject()
{
return _thing;
}
}
public class TrairInspector
{
public void InspectTraitUser(IGetTraitInfo traitUser)
{
Type traitType = traitUser.GetTraintObjectType();
object data = traitUser.GetTraitObject();
}
}
I didn't understand completely but this might help you.
public interface ITrait
{
string DoSomething();
}
public class Trait<T> where T : ITrait, new()
{
public string DoSomething()
{
ITrait trait = new T();
return trait.DoSomething();
}
}
public class TraitUser : ITrait
{
public string DoThing()
{
return "return something";
}
}
public class TrairInspector
{
public void DoThing()
{
Trait<TraitUser> traitUser = new Trait<TraitUser>();
traitUser.DoSomething();
}
}

Return IEnumerable<IMyInterface> from List<MyInterfaceClass>

EDIT: This question would be invalid in .NET 4 since it actually works as desired.
I have a Data class that must implement an interface like this:
public interface IData
{
IEnumberable<IOther> OtherList { get; }
IOther AddOther();
void RemoveOtherData(IOther data);
}
But I am stuck with declaring the actual member in Data
public class Data : IData
{
// desired, always return the same reference
public IEnumberable<IOther> OtherList { get { return _mOtherList } }
// Non persistent reference not desirable.
public IEnumerable<IOther> OtherList { get { return _mOtherList.Select(x => x as IOther); } }
List<IOther> _mOtherList = new List<Other>(); // error, type mismatch
List<Other> _mOtherList = new List<Other>(); // error, property return type mismatch
IEnumerable<IOther> _mOtherList = new List<Other>(); // ok, but cannot use List methods without casting.
}
What would be the best solution in this case?
public class Data : IData
{
public IEnumerable<IOther> OtherList { get; private set; }
List<Other> _mOtherList = new List<Other>();
public Data()
{
OtherList=mOtherList.Cast<IOther>();
}
}
On .net 4 IEnumerable<out T> is co-variant. i.e. a class that implements IEnumerable<Other> automatically implements IEnumerable<IOther> too. So could also simply write:
public class Data : IData
{
public IEnumerable<IOther> OtherList { get{return mOtherList;} }
List<Other> _mOtherList = new List<Other>();
}
But I'd avoid that, since it breaks encapsulation and allows outsiders to modify your list.
((List<Other>)MyData.OtherList).Add(...);
Other class must implement IOther interface and you don't need to cast.
When you declare _mOtherList, it's IEnumerable, so you can't use list methods. Declare it as a list.
public class Data : IData
{
List<IOther> _mOtherList = new List<Other>();
public IEnumberable<IOther> OtherList { get { return _mOtherList } }
IOther AddOther()
{
return null;
}
void RemoveOtherData(IOther data){}
}
Your Other class:
class Other : IOther
{
//some members
}
As IEnumerable is covariant this is fine:
public interface IInterface{}
public class ClassA : IInterface{}
public class ClassB
{
private readonly List<ClassA> _classAs;
public IEnumerable<IInterface> Data{ get { return _classAs; } }
}

Invoke a Method anonymous class

I am quite new to the C# world and I apologize if the Question title not exactly match the content. But now to my Problem:
I have the following construct:
public interface IClass<TEnum>
{
Dictionary<TEnum, ISecondClass> dictionary { get; }
}
public abstract class ClassBase<TEnum> : IClass<TEnum>
{
public abstract Dictionary<TEnum, ISecondClass> dictionary { get; protected set; }
}
public class ConcreteClass : ClassBase<ConcreteClass.Concrete>
{
public override Dictionary<Concrete, ISecondClass> dictionary { get; protected set; }
public enum Concrete : ulong
{
}
}
public class OtherClass : ClassBase<OtherClass.Other>
{
public override Dictionary<Concrete, ISecondClass> dictionary { get; protected set; }
public enum Other : ulong
{
}
}
My goal is to instantiate all existing concrete classes based on it's enums, store all instances in a dictionary and later invoke some methods on each object.
I am not sure if this is even possible?
I am glad for any hint on this!
If I understand what you're trying to do, it sounds like a version of the Multiton Pattern. You may find it useful to research that.
From Wikipedia's example Multiton code:
class FooMultiton
{
private static readonly Dictionary<object, FooMultiton> _instances = new Dictionary<object, FooMultiton>();
private FooMultiton() {}
public static FooMultiton GetInstance(object key)
{
lock (_instances)
{
FooMultiton instance;
if (!_instances.TryGetValue(key, out instance))
{
instance = new FooMultiton();
_instances.Add(key, instance);
}
}
return instance;
}
}
This isn't directly pasteable into your class, but since you're looking for hints, I think it should point you in the right direction.
One word of caution about the above code: The method GetInstance will alter the dictionary if key isn't found. Personally, I associate the "Get" prefix with read-only methods. I'd either rename GetInstance or split it into two methods.
I'm not really sure what you mean by "instantiate all existing concrete classes based on it's enums", though. Can you clarify that?
Use Activator.CreateInstance() to create concrete classes' objects and store them into dictionary.
Pass your string classname from Enum and create dynamic class objects. Store them into Dictionary<Enum, ISecondClass>
myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");
or
var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);
While retrieving, based on your enum key, you know what type of instance value represents.
I don't understand a goal of the sample code, but you can write some thing like this:
public interface IClass
{
void MethodToDynamicInvoke();
}
public abstract class ClassBase<T>
: IClass
{
private Dictionary<Type, List<IClass>> instances = new Dictionary<Type, List<IClass>>();
public ClassBase()
{
List<IClass> list;
if (!instances.TryGetValue(typeof(T), out list))
{
list = new List<IClass>();
instances.Add(typeof(T), list);
}
list.Add(this);
}
public abstract void MethodToDynamicInvoke();
public void InvokeMetodOnClassesWithSameEnum()
{
List<IClass> list;
if (instances.TryGetValue(EnumType, out list))
{
foreach (var instance in list)
{
instance.MethodToDynamicInvoke();
}
}
}
}
public class ConcreteClass
: ClassBase<ConcreteClass.Concrete>
{
public ConcreteClass()
: base()
{
}
public override void MethodToDynamicInvoke()
{
throw new NotImplementedException();
}
public enum Concrete : ulong
{
}
}
public class OtherClass : ClassBase<OtherClass.Other>
{
public OtherClass()
: base()
{
}
public override void MethodToDynamicInvoke()
{
throw new NotImplementedException();
}
public enum Other : ulong
{
}
}

Inheriting an already instantiated base object

Is it possible to do something like the following:
public class ChildClass : BaseClass
{
public ChildClass(BaseClass o)
{
base = o;
}
}
Basically, I want a transparent way to wrap a base class inside of other functionality. One example I've thought of is a custom Settings Provider which transparently audits the settings passed through it.
public class SettingsAuditor : SettingsProvider
{
public SettingsAuditor(SettingsProvider o)
{
base = o;
}
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
{
// Log the property change to a file
base.SetPropertyValues(context, propvals);
}
}
Then I could do the following:
mySettingsProvider = new SettingsAuditor(mySettingsProvider);
And all changes would go through the overridden SetPropertyValues before passing to the original object.
I could use a private SettingsProvider member, but then I either cannot inherit from SettingsProvider, or have an entire SettingsProvider (base) not being used at all.
I'm using C# 4.0 and .Net 4.0.
You cannot do base = o;
What you're looking for is the Decorator Pattern), which is a way to compositionally add functionality at runtime (vs. inheritance).
Instead of trying to set the base, you just contain the inner member. As long as the wrapper implements the same interface or base class as the inner object, you can pass back the new wrapper. You can wrap as many decorators as you want.
Consider:
public interface ICar
{
void Drive();
}
public class Car : ICar
{
public void Drive()
{
Console.WriteLine("vroom");
}
}
public class BuckleUp : ICar
{
ICar car;
public BuckleUp(ICar car) { this.car = car; }
public void Drive()
{
Console.WriteLine("click!");
car.Drive();
}
}
public class CheckMirrors : ICar
{
ICar car;
public CheckMirrors(ICar car) { this.car = car; }
public void Drive()
{
Console.WriteLine("mirrors adjusted");
car.Drive();
}
}
Now consider you have a method that accepts an ICar and tells it to drive. You could give it a Car, and it would work, but you could also wrap that car in a BuckleUp and a CheckMirrors and you wouldn't have to change that method at all. You've modified functionality through composition using the Decorator Pattern.
No. This looks like it should be a Composition vs Inheritance issue. You need to evaluate whether you are a "is a" or a "has a."
A little help for your journey
This is not a complete implmentation and it could probably be done much cleaner with expression trees... but this was a quick swing at faking AOP using DynamicObject with .Net 4.0.
public class MyDynamicWrapper<T> : DynamicObject
{
public T Wrapped { get; private set; }
public Action<T> Pre { get; private set; }
public Action<T> Post { get; private set; }
public MyDynamicWrapper(T wrapped, Action<T> pre, Action<T> post)
{
this.Wrapped = wrapped;
this.Pre = pre;
this.Post = post;
}
public override bool TryGetMember(
GetMemberBinder binder,
out object result)
{
var type = typeof(T);
var method = type.GetMethod(binder.Name);
if (method != null)
{
Func<object> func = () =>
{
if (Pre != null)
Pre(Wrapped);
// support for input parameters could be added here
var ret = method.Invoke(Wrapped, null);
if (Post != null)
Post(Wrapped);
return ret;
};
result = func;
return true;
}
return base.TryGetMember(binder, out result);
}
}
public class MyDynamicWrapper
{
public static MyDynamicWrapper<T> Create<T>(
T toWrap,
Action<T> pre = null,
Action<T> post = null)
{
return new MyDynamicWrapper<T>(toWrap, pre, post);
}
}
public class MyObject
{
public void MyMethod()
{
Console.WriteLine("Do Something");
}
}
class Program
{
static void Main()
{
var myobject = new MyObject();
dynamic mydyn = MyDynamicWrapper.Create(
myobject,
p => Console.WriteLine("before"),
p => Console.WriteLine("after"));
// Note that you have no intellisence...
// but you could use the old implmentation before you
// changed to this wrapped version.
mydyn.MyMethod();
/* output below
before
Do Something
after
*/
}
}
No, but you could fake it:
public class SettingsAuditor
{
SettingsProvider #base;
public SettingsAuditor(SettingsProvider o)
{
#base = o;
}
public void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
{
// Log the property change to a file
#base.SetPropertyValues(context, propvals);
}
}
Note here, #base isn't the actual base, just a varaible named base

Unable to perform cast

I need to have a wrapper class that exposes some properties of my entity class called ProfileEntity.
I tried doing it by deriving from this entity and then creating properties that return specific entity properties, but it says I cannot cast from ProfileEntity to ProfileEntityWrapper.
When I try to put the return values of a method that returns a 'ProfileEntity' into the wrapper I get the above error.
How do I create such a wrapper class that is castable?
Example
class ProfileEntityWrapper : ProfileEntity
{
public string Name
{
get
{
return this.ProfileEntityName;
}
}
}
public class Someclass
{
public ProfileEntity SomeMethod()
{
return ProfileEntity; // example of method returning this object
}
}
public class SomeOtherlClass
{
SomeClass sc = new SomeClass();
public void DoSomething()
{
ProfileEntityWrapper ew = (ProfileEntityWrapper)sc.SomeMethod(); // Cannot do this cast!!!
}
}
You cannot cast an object of ProfileEntity to ProfileEntityWrapper.
var entity = new ProfileEntity(); // this object is only of type ProfileEntity
var wrapper = new ProfileEntityWrapper(); // this object can be used as both ProfileEntityWrapper and ProfileEntity
You probably want to return a ProfileEntityWrapper in SomeMethod():
public class Someclass
{
public ProfileEntity SomeMethod()
{
return new ProfileEntityWrapper(); // it's legal to return a ProfileEntity
}
}
No, that is not possible.
To accomplish this problem you can maybe try this one:
public class ProfileEntity
{
public string ProfileEntityName { get; set; }
}
public class ProfileEntityWrapper
{
public ProfileEntityWrapper(ProfileEntity entity)
{
Entity = entity;
}
public ProfileEntity Entity { get; private set; }
public string Name
{
get
{
return Entity.ProfileEntityName;
}
}
}
public class SomeClass
{
public ProfileEntity SomeMethod()
{
// example of method returning this object
ProfileEntity temp = new ProfileEntity();
return temp;
}
}
public class SomeOtherClass
{
SomeClass sc = new SomeClass();
public void DoSomething()
{
//Create a new Wrapper for an existing Entity
ProfileEntityWrapper ew = new ProfileEntityWrapper(sc.SomeMethod());
}
}
If you are allowed to edit the ProfileEntity class, or if the ProfileEntity class is a generated partial class, you could add an interface instead of using a wrapper. You wouldn't need to do any casting with an interface either. Example:
public interface IProfile
{
string Name { get; }
}
public partial class ProfileEntity : IProfile
{
public string Name
{
get
{
return this.ProfileEntityName;
}
}
}
public class SomeClass
{
public ProfileEntity SomeMethod()
{
return ProfileEntity;
}
}
public class SomeOtherClass
{
SomeClass sc = new SomeClass();
public void DoSomething()
{
IProfile ew = sc.SomeMethod();
}
}
The IProfile instance will only provide access to the Name property.
This's no correct code from polymorphism aspect.
If we will take the famous polymorphism example when there're base Shape class and Circle, Polygon and Rectangle classes that extend the Shape class, your code will try to cast some shape into circle and as you understand this's invalid casting operation.
So to make this code work you must be sure that SomeClass.SomeMethod() will return instance of ProfileEntityWrapper or perform type check before the casting, like this:
ProfileEntity temp = sc.SomeMethod();
if(temp is ProfileEntityWrapper)
ProfileEntityWrapper ew = (ProfileEntityWrapper) temp;

Categories

Resources