Explicit and Implicit Common Type Listing

I have these 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 mine:

 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 pass DiscountFilter

in an FilterBackOfficeDiscountFilterType

explicit or implicit way.

So, I add an 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 doesn't compile because:

Cannot implicitly convert type 'Filter<DiscountFilterType>' to 'FilterBackOfficeDiscountFilterType'

      

How can i do this?

DiscountFilterType

is an enumeration.

And FilterCreator.Create:

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 comes from:

public abstract class FilterCreator<T>
    where T : struct
{
    public abstract Filter<T> Create(T type, string value);
}

      

And the last one Filter

:

public abstract class Filter<T>
    where T : struct
{
    public T Type { get; set; }
    public string Value { get; set; }
}

      

Edit to reproduce the problem you should 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 like this:

    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 implicit casting from the inherited class to the base is not allowed!

DiscountFilter.implicit operator DiscountFilter(Filter<DiscountFilterType>): user-defined conversions to or from a base class are not allowed   

      

+3


source to share


2 answers


(Implicit) custom conversions from base class to derived class are a bad idea and, as such, are not supported by the language, as already explained here: Custom conversion operator from base class

As a solution to your problem, I would suggest setting up the base types like this:

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 simply implement DiscountFilterCreator like



public class DiscountFilterCreator : FilterCreator<DiscountFilter, DiscountFilterType>
{
    public override DiscountFilter Create(DiscountFilterType type, string value)
        => new DiscountFilter { Type = type, Value = string.IsNullOrWhiteSpace(value) ? null : value };
}

      

By using this, you don't need to cast any more since the return type is expected.

Not sure if this is exactly what you want. The code seems very abstract by the C # standard, there is probably a better design for your needs.

EDIT: As a side note, this implementation makes it FilterCreator

very close to useless. The usefulness Filter<T>

also seems rather dubious - do you ever declare a variable or a generic type constraint Filter<T>

?

+3


source


To reproduce your problem, you are trying to apply a base generic class to a derived class.

something like that

DiscountFilter filter = new DiscountFilterCreator().Create(DiscountFilterType.normal, "wow"); 

      



to solve your problem you should apply to the derived class

 DiscountFilter filter =(DiscountFilter) new DiscountFilterCreator().Create(DiscountFilterType.normal, "wow"); 

      

+1


source







All Articles