Reputation: 4433
I have 3 classes as mentioned below: One has the information for removal, rest two classes have actual data. In future there will be more than 30 classes for data
public class RemovalInformation<T> where T:class
{
public string TagName { get; set; }
public T Data { get; set; }
public Func<T, bool> RemovalCondition { get; set; }
}
public class PropertyReportData
{
public string PropertyName { get; set; }
}
public class ValuationData
{
public DateTime ValuationDate { get; set; }
}
I have a below ArrayList which I want to process
var removals = new ArrayList
{
new RemovalInformation<PropertyReportData>
{
Data = commercialReportData?.PropertyDetail,
TagName = nameof(PropertyReportData.PropertyName),
RemovalCondition = property => string.IsNullOrWhiteSpace(property.PropertyName),
},
new RemovalInformation<ValuationData>
{
Data = commercialReportData?.ValuationData,
TagName = nameof(ValuationData.ValuationDate),
RemovalCondition = property => property.ValuationDate< DateTime.Today,
}
};
ProcessRemovals(removals);
Method ProcessRemovals is
private void ProcessRemovals(ArrayList removals)
{
foreach (RemovalInformation<PropertyReportData> item in removals)
{
var deleteItem = item.RemovalCondition.Invoke(item.Data);
if (deleteItem)
{
//do something here
}
}
}
The problem here is, in foreach loop I can access RemovalInformation of only one type. Is there any way to iterate over the list for multiple types of RemovalInformation
Upvotes: 3
Views: 2590
Reputation: 881
Add using System.Linq;
at the start of the file and apply .OfType<T>()
to filter only a certain type of items in the collection (where T
is the type you need):
foreach (RemovalInformation<PropertyReportData> item in removals.OfType<RemovalInformation<PropertyReportData>>())
{
//do something here
}
Upvotes: 0
Reputation: 16150
You can alternatively use dynamic
type:
private void ProcessRemovals(ArrayList removals)
{
foreach (dynamic item in removals)
{
var deleteItem = item.RemovalCondition.Invoke(item.Data);
if (deleteItem)
{
//do something here
}
}
}
Upvotes: 0
Reputation: 874
As answered by @mtanksl, in order to be able to access to common properties/methods that all the types shares, you will have to define an interface (or abstract class). but for the specific types you can use c# 7(and above) pattern matching:
private static void ProcessRemovals(ArrayList removals)
{
foreach (var r in removals)
{
switch(r)
{
case RemovalInformation<PropertyReportData> propertyReportData:
//do delete with propertyReportData
break;
case RemovalInformation<ValuationData> valuationData:
//do delete with valuationData
break;
default:
var removalInfo = (IRemovalInformation)r;
//do delete with removalInfo that should holds all the common properties and methods
break;
}
}
}
Upvotes: 2
Reputation: 601
You could use an interface, something like this:
public interface IProcessRemoval
{
bool Execute();
}
Just implement it:
public class RemovalInformation<T> : IProcessRemoval where T:class
{
public string TagName { get; set; }
public T Data { get; set; }
public Func<T, bool> RemovalCondition { get; set; }
public bool Execute()
{
if (RemovalCondition != null)
{
return RemovalCondition(Data);
}
return false;
}
}
Then iterate:
private void ProcessRemovals(ArrayList removals)
{
foreach (IProcessRemoval item in removals)
{
var deleteItem = item.Execute();
if (deleteItem)
{
//do something here
}
}
}
Upvotes: 5