i have a class that has multiple lists i.e.City
, State
and Country
as a member of that class , now i want to make a generalize function where in
user can pass the id of country or state or city , it will delete that specific record. I have common out the elements i.e. id by implementing IEntity
interface to each class so that i can delete specific city , country and state based on id
so that i can perform deleteDataFromNotification<City>("23323")
But the issue over here is IList
. Is there a way to create such a function that accepts MatserInfo
and automatically get the required list and delete off the entity.
something like , where getEntityList fetch the list automatically
var data = realm.All<MasterInfo>().getEntityList().Where(d => d.id == id).FirstOrDefault();
following is my code
void deleteData<T>(String id) where T : RealmObject, IEntity{
Realm realm = Realm.GetInstance();
try
{
var data = realm.All<T>().Where(d => d.id == id).FirstOrDefault();
realm.WriteAsync(tempRealm =>
{
if (data != null)
tempRealm.Remove(data);
});
}
catch (Exception e)
{
Debug.WriteLine("Exception " + e.Message);
}
}
public class MasterInfo : RealmObject {
[JsonProperty("listCityMaster", NullValueHandling = NullValueHandling.Ignore)]
public IList<City> cityList { get; }
[JsonProperty("listStateMaster", NullValueHandling = NullValueHandling.Ignore)]
public IList<State> stateList { get; }
[JsonProperty("listCountryMaster", NullValueHandling = NullValueHandling.Ignore)]
public IList<Country> countryList { get; }
}
public class Country : RealmObject,IEntity
{
[PrimaryKey]
public String id { get; set; }
public String name { get; set; }
}
public class State : RealmObject,IEntity
{
public String countryId { get; set; }
[PrimaryKey]
public String id { get; set; }
public String name { get; set; }
}
public class City : RealmObject,IEntity
{
public String countryId { get; set; }
[PrimaryKey]
public String id { get; set; }
public String name { get; set; }
public String stateId { get; set; }
}
public interface IEntity
{
String id { get; set; }
}
For the example shown, you could implement GetEntityList<T>
in the MasterInfo class as follows. As written, this will return null, not an error, if called with a non-matching type.
public IList<T> GetEntityList<T>()
{
return (cityList as IList<T>) ?? (stateList as IList<T>) ?? (countryList as IList<T>);
}
Edit: Show a more dynamic way.
This version creates a list of properties that implement IList and caches the property getters in a static dictionary variable. When you call GetEntityList, it uses the appropriate getter to return the matching list.
The reflection to get the matching properties is run once when your application first executes this code. The reflection to get the property value is executed whenever you call GetEntityList.
static Dictionary<Type, PropertyInfo> DictionaryOfILists = typeof(MasterInfo)
.GetProperties()
.Where(v => v.PropertyType.IsGenericType && v.PropertyType.GetGenericTypeDefinition() == typeof(IList<>))
.ToDictionary(v => v.PropertyType, v => v);
public IList<T> GetEntityList<T>()
{
return DictionaryOfILists[typeof(IList<T>)].GetValue(this) as IList<T>;
}