What's the best way to implement a dynamic property in a C # object?
I have several class objects, each requiring a url field that is always formatted in the same way via a parameter TypeId
, another property of the class.
What is the best way to abstract this as a dynamic property, so the url field is generated based on properties TypeId
and ItemId
from a class.
I can think of many ways to do this, but was wondering what the recommended practice is.
See example below:
public class MyObject
{
public int Id { get; set; }
public string URL
{
get
{
if (TypeId == 3)
{
return "/do/this/" + ItemId;
}
if (TypeId == 5)
{
return "/do/that/" + ItemId;
}
return "#";
}
}
public int ItemId { get; set; }
public int TypeId { get; set; }
}
source to share
You can set up a dictionary with all known TypeIds and Func<int, string>
to return a URL. You can even make it possible to add new TypeIds and URL formatting functions at runtime:
private Dictionary<int, Func<int, string>> _urlFormatters;
public string URL
{
get { return _urlFormatters[TypeId](ItemId); }
}
// In the constructor or some other init area:
{
_urlFormatters = new Dictionary<int, Func<int, string>>
{
{ 3, itemId => "/do/this/" + itemId },
{ 5, itemId => "/do/that/" + itemId }
};
}
source to share
You can take it one step further and implement its full object:
public abstract class MyObject
{
public int ItemId { get; set; }
public virtual string URL { get { return "#"; } }
}
public class MyObjectType3 : MyObject
{
public override string URL { get { return "/do/this/" + ItemId; } }
}
public class MyObjectType5 : MyObject
{
public override string URL { get { return "/do/that/" + ItemId; } }
}
It depends if you have many types, if this logic makes sense or not.
It's just a different solution, but the one you give looks good too.
source to share
abstract class BaseClass {
public int ItemId { get; set; }
public abstract string BaseUrl { get; }
public string Url {
get {
return BaseUrl + ItemId;
}
}
}
class Type3 : BaseClass {
public override string BaseUrl {
get { return "/do/this/"; }
}
}
class Type5 : BaseClass {
public override string BaseUrl {
get { return "/do/that/"; }
}
}
source to share