Coming from Java, I think I should be able to do something like this:
using System.Collections.Generic;
interface ICoord<T> where T : ICoord<T>
{
ICollection<T> GetNeighbors();
}
class SquareCoord : ICoord<SquareCoord>
{
public ICollection<SquareCoord> GetNeighbors() {
throw new System.NotImplementedException();
}
}
interface IGrid<T> where T : ICoord<T>
{
List<T> GetGrid();
}
// This works no problem (everything is concretely defined)
class SquareGrid : IGrid<SquareCoord>
{
public List<SquareCoord> GetGrid() {
throw new System.NotImplementedException();
}
}
class Grid : IGrid<ICoord>
{
public List<ICoord> GetGrid()
{
//do stuff
}
}
where the last class Grid should be able to operate and return a List of any (concrete implementation of) ICoord.
I have a small working example in Java. If I could get the equivalent (if possible) in C#, that would give me enough to go on.
public class Example {
private interface Index<T extends Index> {
List<T> GetNeighbors();
}
private static class SquareIndex implements Index<SquareIndex> {
public List<SquareIndex> GetNeighbors(){
return new ArrayList<>();
}
}
private interface Grid<T extends Index> {
List<T> GetGrid();
}
// Java does not require a type parameter to implement "Grid"
private static class MyGrid implements Grid {
// Java allows me to satisfy the requirements for implementing "Grid"
// without having a concrete type defined in the method declaration.
public List<? extends Index> GetGrid() {
final List<SquareIndex> result = new ArrayList<>();
result.add(new SquareIndex());
return result;
}
}
public static void main(String[] args) {
MyGrid g = new MyGrid();
g.GetGrid();
}
}
My excellent girlfriend just figured it out:
class MyGrid<T> : IGrid<T> where T : ICoord<T>
{
public List<T> GetGrid() {
throw new System.NotImplementedException();
}
}
Related
This is what I want to do in C# (within class Helper - without generic arguments),
List<AbstractClass<dynamic>> data;
public void Add<T>(AbstractClass<T> thing)
{
this.data.Add((AbstractClass<dynamic>) thing);
}
This helper class would take and work with AbstractClass<> objects and give back AbstractClass<> of specific generic type. AbstractClass<T> contains many functions which return T / take in T like public T Invoke().
For Helper class T cannot be known beforehand. The Add<T>(.. thing) function is not in a class of type T.
To be used like this in Helper class's functions,
foreach(var c in data.Where(x => ...))
{
// public T Invoke() { ... } function within AbstractClass<T>
var b = c.Invoke();
// logic
}
This also fails,
List<AbstractClass<object>> data;
public void Add<T>(AbstractClass<T> thing)
{
this.data.Add((AbstractClass<object>) thing);
}
Now I think I can have,
List<dynamic> data; // or List<object> data;
public void Add<T>(AbstractClass<T> thing)
{
this.data.Add(thing);
}
but I want the constraint that List named data has only elements of type like
ConcreteClass : AbstractClass<OtherClass>
So we would know that there is an public T Invoke() function but we do not know what it returns. This is helpful to avoid mistakes of say misspelling Invocke and only knowing at run-time.
I want to avoid casting to dynamic every time to invoke functions that give back generic type T
To do what you want to do you are going to need to use a Contravariant interface
public class Program
{
static void Main()
{
var m = new Helper();
m.Add(new ConcreteClass());
m.Process();
}
class Helper
{
List<IAbstractClass<OtherClassBase>> data = new List<IAbstractClass<OtherClassBase>>();
public void Add(IAbstractClass<OtherClassBase> thing)
{
this.data.Add(thing);
}
public void Process()
{
foreach(var c in data.Where(x => x.ShouldBeProcessed()))
{
var b = c.Invoke();
Console.WriteLine(b.Question);
var castData = b as OtherClass;
if (castData != null)
Console.WriteLine(castData.Answer);
}
}
}
public interface IAbstractClass<out T>
{
bool ShouldBeProcessed();
T Invoke();
}
abstract class AbstractClass<T> : IAbstractClass<T>
{
public bool ShouldBeProcessed()
{
return true;
}
public abstract T Invoke();
}
class ConcreteClass : AbstractClass<OtherClass>
{
public override OtherClass Invoke()
{
return new OtherClass();
}
}
class OtherClassBase
{
public string Question { get { return "What is the answer to life, universe, and everything?"; } }
}
class OtherClass : OtherClassBase
{
public int Answer { get { return 42; } }
}
}
You do not need to tell Add what kind of class you are passing it, all that matters is it derives from the type specified. You could do public void Add(IAbstractClass<object> thing) and every class would work, but Invoke() would only return objects inside the foreach loop.
You need to figure out what is the most derived class you want Invoke() to return and that is what you set as the type in the list.
Maybe this will work for you:
public class Program
{
static void Main()
{
var m1 = new Helper<OtherClass>();
m1.Add(new ConcreteClass());
var m2 = new Helper<int>();
m2.Add(new ConcreteClass2());
}
class Helper<T>
{
List<AbstractClass<T>> data = new List<AbstractClass<T>>();
public void Add<T1>(T1 thing) where T1 : AbstractClass<T>
{
this.data.Add(thing);
}
}
class AbstractClass<T> { }
class OtherClass { }
class ConcreteClass : AbstractClass<OtherClass> { }
class ConcreteClass2 : AbstractClass<int> { }
}
I would like to be able to present a choice to the user - whether to use 16bit indices (in OpenGL) or 32bit indices. In C++, I'd probably just create an alias for int or short, but I don't seem to have the option in C#. Basically what I'm going for can be summed up in the class below:
using System;
namespace Something
{
public class Conditional
{
public Conditional(Boolean is16Bit)
{
if (is16Bit)
{
SOMETYPE is Int16
}
else
{
SOMETYPE is Int32
}
}
private List<SOMETYPE> _something;
}
}
The aliasing (if it can be done) would be vastly better - I just don't want to force anyone using this code into writing #define statements, is that possible?
Thanks
Seems like you could use a generic for this:
namespace Something
{
public class Conditional<T>
{
private List<T> _something = new List<T>();
private Conditional()
{
// prevents instantiation except through Create method
}
public Conditional<T> Create()
{
// here check if T is int or short
// if it's not, then throw an exception
return new Conditional<T>();
}
}
}
And to create one:
if (is16Bit)
return Conditional<short>.Create();
else
return Conditional<int>.Create();
You can use an interface and a factory, something like this:
public interface IConditional
{
void AddIndex(int i);
}
private class Conditional16 : IConditional
{
List<Int16> _list = new List<Int16>();
public void AddIndex(int i)
{
_list.Add((short)i);
}
}
private class Conditional32 : IConditional
{
List<Int32> _list = new List<Int32>();
public void AddIndex(int i)
{
_list.Add(i);
}
}
public static class ConditionalFactory
{
public static IConditional Create(bool is16Bit)
{
if (is16Bit)
{
return new Conditional16();
}
else
{
return new Conditional32();
}
}
}
Your code (and callers of it) can do everything against IConditional without caring which of the concrete representations it is.
I have got a abstract class with an abstract method taking a parameter of the type of the implementing class. I can achieve this by generics like this:
abstract class Clazz<T>
{
public abstract void CopyFrom(Clazz<T> source);
}
class MyClass : Clazz<MyClass>
{
public override void CopyFrom(Clazz<MyClass>)
{
// implementation
}
}
Unfortunately I need in one of the implementing classes a list of Clazz<T> elements.
So how can I achieve this?
Of cause List<Clazz<T>> does not work.
List<Clazz<MyClass>> is too restrictive.
Removing the generics and the abstract method does work (my current solution), but this way I could forget to implement the CopyFrom() method in one of the implementing classes.
Edit: Here comes a more detailed example:
I've got an abstract class:
abstract class Clazz<T>
{
public abstract void CopyFrom(Clazz<T> source);
// ...
}
And a derived class:
class MyDerivedClass : Clazz<MyDerivedClass >
{
public string Text;
private readonly List<MySubClass> _list = new List<MySubClass>();
public override void CopyFrom(MyDerivedClass source)
{
Text = source.Text;
}
private List<Clazz> GetAllItems()
{
List<Clazz> list = new List<Clazz>();
list.Add(this);
list.AddRange(_list);
}
private class MySubClass : Clazz<MySubClass>
{
public int Number;
public override void CopyFrom(MySubClass source)
{
Number = source.Number;
}
}
}
There are several other deriving classes, the GetAllItems() Method is only needed in MyDerivedClass.
would this suffice? without more details it is hard to tell.
interface ICopyMaker
{
void CopyFrom(ICopyMaker source);
}
abstract class Clazz<T> : ICopyMaker
{
public abstract void CopyFrom(Clazz<T> source);
void ICopyMaker.CopyFrom(ICopyMaker source)
{
var src = source as Clazz<T>;
if (src == null) return; // know how to copy only from the instances of the same type
CopyFrom(src);
}
}
class MyClass : Clazz<MyClass>
{
private List<ICopyMaker> _list = new List<ICopyMaker>();
public override void CopyFrom(Clazz<MyClass> c)
{
//implementation
}
}
You can make the respective method generic, too, and introduce a constraint that takes T into account. If I understand well what you want to achieve, you can do this:
abstract class Clazz<T>
{
public abstract void CopyFrom(Clazz<T> source);
public abstract void ProcessList<TDescendant>(List<TDescendant> list)
where TDescendant : Clazz<T>;
}
class MyClass : Clazz<MyClass>
{
public override void CopyFrom(Clazz<MyClass> source)
{
// implementation
}
public override void ProcessList<TDescendant>(List<TDescendant> list)
{
// implementation
}
}
You can also easily include list processing in a descendant, like this:
class MyOtherClass : Clazz<MyOtherClass>
{
public override void CopyFrom(Clazz<MyOtherClass> source)
{
// implementation
}
// this list processing is inherited
public override void ProcessList<TDescendant>(List<TDescendant> list)
{
// implementation
}
// this list processing is specific to this descendant only
public void ProcessMyClassList<TDescendant>(List<TDescendant> list)
where TDescendant : Clazz<TMyClass>
{
// implementation
}
}
Then use can declare a descendant of MyClass, which in turn is a Clazz<T>, T being MyClass:
class MyDescendant : MyClass
{
}
The following works:
List<MyDescendant> list = new List<MyDescendant>();
new MyClass().ProcessList(list);
In case of MyOtherClass, the situation is a little bit different. ProcessMyClassList accepts a list of Clazz<T> or its descendants; however, not those related to MyOtherClass but to the good-ol' MyClass. This code works:
List<MyDescendant> list = new List<MyDescendant>();
new MyOtherClass().ProcessMyClassList(list); // this works
But the following won't compile:
List<MyOtherClass> list = new List<MyOtherClass>();
new MyOtherClass().ProcessList(list); // this works
new MyOtherClass().ProcessMyClassList(list); // this doesn't
Thank's everyone for your answers, but I think I have figured out a solution I can live with:
I will remove the generics and add a typecheck, like in the solution from anikiforov:
Abstract class:
abstract class Clazz
{
public abstract void CopyFrom(Clazz source);
}
And the derived class:
class MyDerivedClass : Clazz
{
public string Text;
private List<MyNestedClass> _list;
public override void CopyFrom(Clazz source)
{
var src = source as MyDerivedClass;
if (src == null) return;
Text = src.Text;
}
public List<Clazz> GetAllItems()
{
var list = new List<Clazz>();
list.Add(this);
list.AddRange(_list);
return list;
}
class MyNestedClass : Clazz
{
public int Number;
public override void CopyFrom(Clazz source)
{
var src = source as MyNestedClass;
if (src == null) return;
Number = src.Number;
}
}
}
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; } }
}
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
{
}
}