how to implement collection objects of my class?
something like MatchCollection or CookieCollection
For example:
I have the following class:
public class theParserClass
{
public theParserClass(string baa)
{
//..
}
public string pro1
{
get { /* etc */ }
}
}
and the collection that I want to implement:
public class theParserClassResultCollection
{
private ParserResultCollection result;
public theParserClassResultCollection(string[] baa)
{
foreach(string foo in baa)
{
var data = new theParserClass(foo);
result.Add(data);
}
}
public ParserResultCollection()
{
return result;
}
}
I hope this is clear. Thanks in advance
you can use the ObservableCollection like this:
public ObservableCollection<ParserClass> GetCollection(string[] baa)
{
var result = new ObservableCollection<ParserClass>();
foreach(string foo in baa)
{
var data = new ParserClass(foo);
result.Add(data);
}
return result;
}
public class ParserClass
{
public ParserClass (string baa)
{
//..
}
public string pro1
{
get { /* etc */ }
}
}
msdn : http://msdn.microsoft.com/en-us/library/ms668604.aspx
hope this helps
First off, you are declaring what appears to be the constructor of ParserResultCollection inside the class theParserResultCollection. Don't really know what that is supposed to mean.
The general idea you can use is to make a wrapper class over an existing collection (inheritance by composition) and provide the methods that you need using the inner collection object. Like:
public class ParserResultCollection
{
private List<ParserClass> collection;
public ParserResultCollection(string[] param)
{
collection = new List<ParserClass>(param);
}
public void Add(ParserClass item)
{
collection.Add(item);
}
// whatever else you need.
}
Of course, if you don't need any other special functionality with respect to the existing collections, just use them instead.
And drop the "the", just ParserResultCollection. It's cleaner.
You could try this:
public class Collection<T> : IList<T>,
ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
http://msdn.microsoft.com/en-us/library/ms132397.aspx
Related
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();
}
}
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.
Please observe the following code:
public class MyClass
{
List<object> _List = new List<object>();
public List<object> Objects { get { return _List; } }
public List<string> Strings { get { return _List.Cast<string>().ToList(); } }
public void Test()
{
Objects.Add ("Hello");
// actual contents
// Objects = object[] { "Hello" }
// Strings = string[] { "Hello" }
Strings.Add ("World");
// actual contents
// Objects = object[] { "Hello" }
// Strings = string[] { "Hello" }
// expected contents
// Objects = object[] { "Hello", "World" }
// Strings = string[] { "Hello", "World" }
}
}
The code shows a class with a list of objects. The two properties expose that list as List<object> and List<string> respectively. However, since _List.Cast<string>().ToList() creates a COPY of the actual list, the line Strings.Add ("World") doesn't affect the actual list. Is there a way to ensure a CASTED REFERENCE to the actual list is returned in the Strings property instead of a CASTED COPY of the actual list?
Note: The code can fail when an integer is added to Objects and then accessed from Strings but that's not what I'm worried about at the moment.
EDIT
The original question was as follows. It was changed to avoid confusion and simplify the problem at hand. Observe the following code:
public abstract class Foo
{
List<object> _List = new List<object>();
public List<object> ListObject { get { return _List; } }
}
public class Bar : Foo
{
public List<string> ListString
{
get { return ListObject.Cast<string>().ToList(); }
}
}
Bar oBar = new Bar();
Foo oFoo = oBar;
oFoo.ListObject.Add("Item");
// oFoo.ListObject= { "Item" }
// oBar.ListString = { "Item" }
oBar.ListString.Add("NewItem");
// oFoo.ListObject= { "Item" }
// oBar.ListString = { "Item" }
As you can see, using the base class object works fine (an item is added to the internal list), but using the derived class object does not work. I know the reason is because casting a List to List actually creates a new copy of the list and returns that instead. I'm wondering if it is possible to write these classes such that it works both ways.
You can try something like this:
public abstract class Foo<T>
{
List<T> _List = new List<T>();
public List<T> ListObject { get { return _List; } }
}
public class Bar : Foo<string>
{
public List<string> ListString
{
get { return ListObject; }
}
}
Result:
I was hoping that someone else would come up with a reasonably good answer to this, but the reality is that there's probably not a good answer to this one.
However, there are several ways to skin your average cat, many of them pretty ugly.
One ugly solution to this problem is to implement a list class that encapsulates n List<object> object and attempts to access the objects as whatever type you choose. This type of proxy class can be awkward to get right, but might be a way to do what you're trying to do.
public class StringObjectList : IList<string>
{
private List<object> _list;
public StringObjectList(List<object> src)
{
_list = src;
}
// IList Implementation...
public string this[int index]
{
get
{
object obj = _list[index];
if (obj == null)
return null;
return obj.ToString();
}
set
{
_list[index] = value;
}
}
// ... plus 3 more IList<string> methods (IndexOf, Insert, RemoveAt)
// ICollection<string> implementation (5 methods, 2 properties)
// IEnumerable<string> implementation (1 method)
// IEnumerable implementation (1 method)
}
Some of the implementation details are a little tricky. Mostly though the implementations are simple proxy methods, since the underlying list is happy to accept strings as well as any other object. The ICollection<string>.Add method for instance can be as simple as:
public void Add(string item)
{
_list.Add(item);
}
Where you might have trouble is with the IEnumerable<string> and IEnumerable implementations, which might require you to create a couple of supporting classes.
Not simple, not elegant, but potentially doable.
If you don't like the generic solution above, you could make the List member abstract.
public abstract class Foo
{
public abstract IList ListObject { get; }
}
public class Bar : Foo
{
public override IList ListObject
{
get { return new List<string>(); }
}
}
public abstract class Foo<T>
{
public abstract IList<T> MyList { get; }
// you can manipulate MyList in this class even if it is defined in inherited class
}
public class Bar : Foo<string>
{
private readonly IList<string> _myList = new List<string>();
public override IList<string> MyList
{
get { return _myList; }
}
}
[TestFixture]
public class TestFixture1
{
[Test]
public void Test()
{
Bar oBar = new Bar();
Foo<string> oFoo = oBar;
oFoo.MyList.Add("Item");
// oFoo.ListObject= { "Item" }
// oBar.ListString = { "Item" }
oBar.MyList.Add("NewItem");
// oFoo.ListObject= { "Item" }
// oBar.ListString = { "Item" }
}
}
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; } }
}