2017-04-14 93 views
3

我有這些類:顯式和隱投與泛型類型

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; } 
} 

而我:

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

和:

public class DiscountFilter : Filter<DiscountFilterType> 
{ 


} 

我想投DiscountFilterFilterBackOfficeDiscountFilterType在明確或隱含的方式。

所以我添加操作方法:

public class DiscountFilter : Filter<DiscountFilterType> 
{ 
    public static implicit operator FilterBackOfficeDiscountFilterType(DiscountFilter filter) 
     => new FilterBackOfficeDiscountFilterType(filterType: filter.Type.ToString(), filterValue: filter.Value); 
} 

但它不會編譯,因爲:

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

我可怎麼辦呢?

DiscountFilterType是一個枚舉。

而且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}; 
} 

它派生自:

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

而在去年Filter是:

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

編輯 重現您有問題要做到這一點

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

編輯

DiscountFilter x = this.FilterCreator.Create(DiscountFilterType.BrandId, brandId); 
     FilterBackOfficeDiscountFilterType y = x; 

編輯 它的工作原理:

DiscountFilter x = (DiscountFilter)this.FilterCreator.Create(DiscountFilterType.BrandId, brandId); 
     FilterBackOfficeDiscountFilterType y = x; 

,但我想這樣做是這樣的:

FilterBackOfficeDiscountFilterType x = this.FilterCreator.Create(DiscountFilterType.BrandId, brandId); 

所以我需要太多這樣的隱式轉換:

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); 
} 

但從derivered類基地隱式轉換是不允許的!

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

所有的代碼在這裏編譯(給定一些拼寫錯誤和重複的類型定義,但沒關係)。 –

+0

你有沒有試過把這個操作符移動到泛型類? –

+0

你不清楚你的問題,因爲你的代碼確實編譯得很好。 – Evk

回答

3

從基類(隱含的)用戶定義的轉換到派生類是一個壞主意因此不支持這裏已經解釋的語言:User-defined conversion operator from base class

作爲您的問題的解決方案,我建議將您的基本類型調整爲如下:

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; } 
} 

然後,你可以實現DiscountFilterCreator作爲

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

利用這一點,你將不再需要強制轉換,因爲返回的類型是預期的類型。

不確定這正是你想要的。代碼看起來非常抽象的C#的標準,很可能有一個更好的設計爲您的需求。

編輯:就像一個側面說明,這個實現呈現FilterCreator非常接近無用。 Filter<T>的用處似乎也頗受質疑 - 你是否曾經聲明過Filter<T>類型的變量或通用約束?

+0

太棒了。它運作良好。 – Nerf

1

要重現您的問題,您試圖將基類泛型轉換爲派生類。

像這樣

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

解決您的問題,你必須強制轉換爲派生類

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

是的,這是很好的方式來做到這一點,但我需要隱式地做。 – Nerf