I have those classes:
public class FilterBackOfficeDiscountFilterType
{
public FilterBackOfficeDiscountFilterType();
public FilterBackOfficeDiscountFilterType(string filterValue = null, string filterType = null);
[JsonProperty(PropertyName = "filterType")]
public string FilterType { get; set; }
[JsonProperty(PropertyName = "filterValue")]
public string FilterValue { get; set; }
}
And my:
public abstract class Filter<T>
where T : struct
{
public T Type { get; set; }
public string Value { get; set; }
}
And:
public class DiscountFilter : Filter<DiscountFilterType>
{
}
I want to cast DiscountFilter
to FilterBackOfficeDiscountFilterType
in explicit or implicit way.
So I add operator method:
public class DiscountFilter : Filter<DiscountFilterType>
{
public static implicit operator FilterBackOfficeDiscountFilterType(DiscountFilter filter)
=> new FilterBackOfficeDiscountFilterType(filterType: filter.Type.ToString(), filterValue: filter.Value);
}
But it do not compile because:
Cannot implicitly convert type 'Filter<DiscountFilterType>' to 'FilterBackOfficeDiscountFilterType'
How I can do it?
DiscountFilterType
is a enum.
And FilterCreator.Create is:
public class DiscountFilterCreator : FilterCreator<DiscountFilterType>
{
public override Filter<DiscountFilterType> Create(DiscountFilterType type, string value)
=> new DiscountFilter {Type = type, Value = string.IsNullOrWhiteSpace(value) ? null : value};
}
It derives from:
public abstract class FilterCreator<T>
where T : struct
{
public abstract Filter<T> Create(T type, string value);
}
And last Filter
is:
public abstract class Filter<T>
where T : struct
{
public T Type { get; set; }
public string Value { get; set; }
}
Edit to reproduce the issue you have to do this
DiscountFilter filter = new DiscountFilterCreator().Create(DiscountFilterType.normal, "wow");
EDIT
DiscountFilter x = this.FilterCreator.Create(DiscountFilterType.BrandId, brandId);
FilterBackOfficeDiscountFilterType y = x;
Edit It works:
DiscountFilter x = (DiscountFilter)this.FilterCreator.Create(DiscountFilterType.BrandId, brandId);
FilterBackOfficeDiscountFilterType y = x;
but I want to do it this way:
FilterBackOfficeDiscountFilterType x = this.FilterCreator.Create(DiscountFilterType.BrandId, brandId);
So I need this implicit conversion too:
public class DiscountFilter : Filter<DiscountFilterType>
{
public static implicit operator DiscountFilter(Filter<DiscountFilterType> filter)
=> new DiscountFilter {Value = filter.Value};
public static implicit operator FilterBackOfficeDiscountFilterType(DiscountFilter filter)
=> new FilterBackOfficeDiscountFilterType(filterType: filter.Type.ToString(), filterValue: filter.Value);
}
But the implicit casting from derivered class to base is not allowed!
DiscountFilter.implicit operator DiscountFilter(Filter<DiscountFilterType>): user-defined conversions to or from a base class are not allowed
(Implicit) user-defined conversions from base class to derived class are a bad idea and as such not supported by the language as already explained here: User-defined conversion operator from base class
As a solution to your problem, I'd propose to adjust your base types as follows:
public abstract class FilterCreator<TFilter, TFilterType>
where TFilter : Filter<TFilterType>
where TFilterType : struct
{
public abstract TFilter Create(TFilterType type, string value);
}
public abstract class Filter<T>
where T : struct
{
public T Type { get; set; }
public string Value { get; set; }
}
Then you can just implement the DiscountFilterCreator as
public class DiscountFilterCreator : FilterCreator<DiscountFilter, DiscountFilterType>
{
public override DiscountFilter Create(DiscountFilterType type, string value)
=> new DiscountFilter { Type = type, Value = string.IsNullOrWhiteSpace(value) ? null : value };
}
Using this, you will no longer need casts since the returned type is the expected type.
Not sure this is exactly what you want. The code seems very abstract by C#'s standards, it's probable that there is a better design for your needs.
EDIT: Just as a side note, this implementation renders the FilterCreator
very close to useless. The usefulness of Filter<T>
seems rather questionable as well - do you ever declare a variable or generic contraint of type Filter<T>
?
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments