I have class with method remove, it needs to delete Customer from CustomerList.
public class ObservableList<T>
{
List <T> CustomerList = new List<T>();
public void Remove(ObservableList<Customer> list) // not correct
{
//something for delete from list;
}
}
indexer in this class:
public T this[int indexer]
{
get { return CustomerList[indexer]; }
set { CustomerList.Add(value); }
}
The string for testing this method looks like this:
ObservableList<Customer> list = new ObservableList<Customer>();
LoadFromBin(list, "source1.bin");
list.Remove(list[2]);
The question is, how to properly format the input data for this method(Remove)? And is the indexer executed correctly in my code?
Based on the attempted usage Remove should accept T, not a collection:
public class ObservableList<T>
{
List <T> CustomerList = new List<T>();
public void Remove(T toRemove) => CustomerList.Remove(toRemove);
}
But again, based on usage it seems you should consider implementing RemoveAt:
public class ObservableList<T>
{
List <T> CustomerList = new List<T>();
public void Remove(T toRemove) => CustomerList.Remove(toRemove);
// usage: list.RemoveAt(2);
public void RemoveAt(int index) => CustomerList.RemoveAt(index);
}
As for the indexer - it is covered in the docs, your set method should set value for index, not add element:
public T this[int indexer]
{
get { return CustomerList[indexer]; }
set { CustomerList[indexer] = value; }
}
But in general, unless it is some exercise you are doing - consider advice from #Jeroen Mostert in the comments - see if existing collections won't serve your needs better than trying to write your own.
Related
Today, I searched a line of code which was written like:
SomeObject.SomeFunction().SomeOtherFunction();
I am unable to understand this. I tried to search it on Google about this but no luck.
Please help me to understand this.
SomeObject has a function called SomeFunction(). This function returns an object (of an unknown type for us, based on your example). This object has a function called SomeOtherFunction().
The question "how to implement" is a bit vague to answer, though.
Consider the following
public class FirstClass
{
public SecondClass SomeFunction()
{
return new SecondClass();
}
}
public class SecondClass
{
public void SomeOtherFunction()
{
}
}
So the following are equivalent.
FirstClass SomeObject = new FirstClass();
SomeObject.SomeFuntion().SomeOtherFunction();
OR
FirstClass SomeObject = new FirstClass();
SecondClass two = SomeObject.SomeFuntion();
two.SomeOtherFunction();
This is called Fluent coding or method chaining and is a method of programming that allows you to chain commands together. It is very common in LINQ where you might have something like this:
var result = myList.Where(x => x.ID > 5).GroupBy(x => x.Name).Sort().ToList();
This would give you all the records greater than 5, then grouped by name, sorted and returned as a list. The same code could be written in long hand like this:
var result = myList.Where(x => x.ID > 5);
result = result.GroupBy(x => x.Name);
result = result.Sort();
result = result.ToList();
But you can see this is much more long winded.
This style of programming called FluentInterface style.
Eg:
internal class FluentStyle
{
public FluentStyle ConnectToDb()
{
// some logic
return this;
}
public FluentStyle FetchData()
{
// some logic
return this;
}
public FluentStyle BindData()
{
// some logic
return this;
}
public FluentStyle RefreshData()
{
// some logic
return this;
}
}
And the object can be created and method can be consumed as below;
var fluentStyle = new FluentStyle();
fluentStyle.ConnectToDb().FetchData().BindData().RefreshData();
This type of chaining may involve extension methods. These allow addition of new methods to existing classes (even those that you don't have the source code for).
e.g.
public static class StringExtender
{
public static string MyMethod1(this string Input)
{
return ...
}
public static string MyMethod2(this string Input)
{
return ...
}
}
....
public string AString = "some string";
public string NewString = AString.MyMethod1().MyMethod2();
This can be done using extension methods
public class FirstClass
{
}
public class SecondClass
{
}
public class ThridClass
{
}
public static class Extensions
{
public static SecondClass GetSecondClass(this FirstClass f)
{
return new SecondClass();
}
public static ThridClass GetThridClass(this SecondClass s)
{
return new ThridClass();
}
}
}
AND then you can ues
FirstClass f= new FirstClass();
f.GetSecondClass().GetThridClass();
I'd like to somehow pass a parameter into a list when I'm instantiating a new list of certain classes.
More specifically, I'd like to do something like the following:
List<FirstClass>(dataTable);
List<SecondClass>(dataTable);
If the first line of code is called, the constructor will deal with dataTable in a certain way than if the latter is called (FirstClass has different fields).
What I've Tried
namespace DeeMacsNamespace
{
public class FirstClass
{
public String Title { get; set; }
public String Url { get; set; }
}
public class FirstClass : List<FirstClass>
{
public FirstClass(DataTable table)
{
foreach (DataRow row in table.Rows)
{
this.Add(new FirstClass()
{
Title = (String)row["Title"]
});
}
}
}
}
I'm assuming (or at least hoping), the above will work. But how do I then most efficiently reuse this code that reads from a DataTable in a really similar constructor for another list of a certain class? And how do I incorporate a conditional statement to check whether the constructor is from the FirstClass or SecondClass type? I would like to avoid rewriting this for a similar constructor for SecondClass.
If I've understood you correctly, then use something like this:
class MyCollection<T> : Collection<T>
{
public MyCollection(DataTable dataTable, Func<DataRow, T> itemsFactory)
: base(dataTable.Rows.Cast<DataRow>().Select(row => itemsFactory(row)).ToList())
{
}
}
var firstClassCollection = new MyCollection<FirstClass>(dataTable, row => new FirstClass
{
Title = (String)row["Title"],
Url = (String)row["Url"]
});
class FirstClass <T>
{
if (typeof(T) == typeof(FirstClass))
{
// ... snip
}
}
Then have all other classes inherit from FirstClass.
There's some unanswered questions regarding your intent. That being said this generic setup may fit the bill:
public interface ISomeInterface
{
String Title { get; set; }
String Url { get; set; }
}
public class SecondClass : ISomeInterface
{
public String Title { get; set; }
public String Url { get; set; }
}
public class FirstClass : ISomeInterface
{
public String Title { get; set; }
public String Url { get; set; }
}
public class SomeClassCollection<T> : List<T> where T: ISomeInterface, new()
{
public SomeClassCollection(DataTable table)
{
foreach (DataRow row in table.Rows)
{
this.Add(new T()
{
Title = (String)row["Title"]
});
}
}
}
private static void Main()
{
var table = new DataTable();
var collection = new SomeClassCollection<FirstClass>(table);
}
You could write an extension method such as:
public static class DataTableEx
{
public static IList<T> CreateList<T>(this DataTable dt,
Func<DataRow,T> selector)
{
return dt.Rows.Cast<DataRow>().Select(selector).ToList();
}
}
Then use it as follows:
IList<string> myList =
dataTable.CreateList(r => new FirstClass{Title = (string)r["Title"]});
List<FirstClass> MyList1 = dataTable.Rows.Select(Row =>
new FirstClass()
{
Title = (String)Row["Title"]
}
).ToList();
List<SecondClass> MyList2 = dataTable.Rows.Select(Row =>
new SecondClass() { the way you create second class } ).ToList();
First of all, you don't want to have the two classes have the same name (the FirstClass and the ListOfFirstClass).
Second of all, your question is a bit unclear, but I believe you're trying to turn a DataTable into a list of First/SecondClass.
If you have access to the DataTable class, you can have it implement the IEnumerable interface.
Using Linq, you can do comething like:
using System.Linq;
public class DataTable : IEnumerable<T>
{
IEnumerable<T> IEnumerable<T>.GetEnumerator()
{
return from row in rows
where FindIfRowIsOfClass<T>(row)
select new T(row);
}
}
You'll have to implement the generic IEnumerable method as well, and fill out the FindIfRowIsOfClassT method. This will most likely be done by finding out if it has the right fields.
The result is the ability to do
List<FirstClass> listOfFirstClass = new List<FirstClass>(dataTable.GetEnumerator<FirstClass>);
I'm not 100% sure, but you may actually be able to get away with not calling GetEnumerator explicitly, List might do that for you.
If you don't have access to that, you can do it manually:
var enumerableFirstClass = from row in dataTable.rows
where <insert row is FirstClass check>
select new FirstClass(){Title = (string)row["Title"]};
List<FirstClass> listOfFirstClass = new List<FirstClass>(enumerableFirstClass);
Hope this helps.
Happy coding!
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" }
}
}
Consider a domain where a Customer, Company, Employee, etc, etc, have a ContactInfo property which in turn contains a set of Address(es), Phone(es), Email(s), etc, etc...
Here is my abbreviated ContactInfo:
public class ContactInfo : Entity<int>
{
public ContactInfo()
{
Addresses = new HashSet<Address>();
}
public virtual ISet<Address> Addresses { get ; private set; }
public Address PrimaryAddress
{
get { return Addresses.FirstOrDefault(a => a.IsPrimary); }
}
public bool AddAddress(Address address)
{
// insure there is only one primary address in collection
if (address.IsPrimary)
{
if (PrimaryAddress != null)
{
PrimaryAddress.IsPrimary = false;
}
}
else
{
// make sure the only address in collection is primary
if (!Addresses.Any())
{
address.IsPrimary = true;
}
}
return Addresses.Add(address);
}
}
Some notes (I am not 100% sure if these are EF "best practices"):
collection of Address(es) is virtual to allow for lazy loading
private setter on collection prohibits collection replacement
collection is an ISet to insure that there are no duplicate addresses per contact
using AddAddress method I can insure that there is always and at most 1 address which is primary....
I would like (if possible) to prevent adding Addresses via ContactInfo.Addresses.Add() method and to force using of ContactInfo.AddAddress(Address address)...
I am thinking exposing the set of addresses via ReadOnlyCollection but will this work with Entity Framework (v5)?
How would I go about this?
Another option suggested by Edo van Asseldonk is to create a custom collection that inherits its behavior from Collection.
You'd have to make your own implementation for ISet but the principle is the same.
By hiding any methods that modifies the list and marking them as obsolete you effectively get a ReadOnlyCollection but EF will still be able to modify it when it's unboxed as Collection. In my version I've added an implicit operator conversion for List so we don't have to unbox the collection when adding items:
var list = ListProperty.ToList();
list.Add(entity)
ListProperty = list;
Where
public virtual EntityCollection<MyEntity> ListProperty { get; protected set; }
and here's the EntityCollection:
public class EntityCollection<T> : Collection<T>
{
[Obsolete("Unboxing this collection is only allowed in the declarating class.", true)]
public new void Add(T item) { }
[Obsolete("Unboxing this collection is only allowed in the declarating class.", true)]
public new void Clear() { }
[Obsolete("Unboxing this collection is only allowed in the declarating class.", true)]
public new void Insert(int index, T item) { }
[Obsolete("Unboxing this collection is only allowed in the declarating class.", true)]
public new void Remove(T item) { }
[Obsolete("Unboxing this collection is only allowed in the declarating class.", true)]
public new void RemoveAt(int index) { }
public static implicit operator EntityCollection<T>(List<T> source)
{
var target = new EntityCollection<T>();
foreach (var item in source)
((Collection<T>) target).Add(item); // unbox
return target;
}
}
This way you can still run your Linq as usual but will get a proper warning of usage when trying to modify the Collection property. Un-boxing it to a Collection would be the only way:
((Collection<MyEntity>)ListProperty).Add(entity);
One way is to make the ICollection property protected and create a new property of IEnumerable that just returns the list of the ICollection property.
The downside with this is that you are not able to query on addresses through the ContactInfo like get all contactinfo that lives in this city.
This is not possible!:
from c in ContactInfos
where c.Addresses.Contains(x => x.City == "New York")
select c
Code:
public class ContactInfo : Entity<int>
{
public ContactInfo()
{
Addresses = new HashSet<Address>();
}
protected virtual ISet<Address> AddressesCollection { get ; private set; }
public IEnumerable<Address> Addresses { get { return AddressesCollection; }}
public Address PrimaryAddress
{
get { return Addresses.FirstOrDefault(a => a.IsPrimary); }
}
public bool AddAddress(Address address)
{
// insure there is only one primary address in collection
if (address.IsPrimary)
{
if (PrimaryAddress != null)
{
PrimaryAddress.IsPrimary = false;
}
}
else
{
// make sure the only address in collection is primary
if (!Addresses.Any())
{
address.IsPrimary = true;
}
}
return Addresses.Add(address);
}
}
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