我想在這里做的事情有點難以描述。我目前的需求要求我有一個可以實作介面的列舉型別。雖然不是最漂亮的解決方案,但這是我想出的辦法;
public class EnumClass<。 T> where T : Enum : Enum ?
{
public T Value { get; }
public string Name { get; }
public EnumClass(T enumValue)。
{
值 = enumValue。
Name = Enum.GetName(typeof(T), enumValue)。
}
public static EnumClass< T> Parse(string name)?
{
return new EnumClass<T>((T)Enum.Parse(typeof(T), name)) 。
}
下面是一個實作的例子:
public class AnimalTypes : EnumClass<AnimalTypesEnum>, IMyEnumInterface public AnimalTypes (AnimalTypesEnum value>>) 。base(value) { } }
}
public enum AnimalTypesEnum
{
[]
CAT。
[] DOG.
DOG,
[] 馬。
馬。
[] 熊。
熊
}
當我在繼承者上靜態地呼叫Parse時,我必須手動地將結果從基型別投回繼承者型別,因為Parse回傳一個通用的EnumClass<T> 物件。
ex.
AnimalTypes dog = (AnimalTypes)AnimalTypes.Parse("DOG"/span>)。
我的問題本質上是,是否有任何方法來撰寫Parse,使其回傳繼承者的型別,而不是基類?我也希望能夠標記EnumClass<T>抽象,但是如果我現在嘗試這樣做,編譯器將不會編譯Parse,指出我無法創建一個EnumClass<T>型別的抽象實體來回傳。
uj5u.com熱心網友回復:
你需要添加另一個型別引數,以便將Parse的回傳值型別引數化,并使派生/繼承型別被創建。
使用方法。
var bear = EnumClass<AnimalTypesEnum>.Parse<AnimalTypes>("BEAR"/span>)。
//AnimalTypesEnum unchanged。
//AnimalTypes unchanged。
public abstract class EnumClass< TEnum> where TEnum : Enum : Enum
{
public TEnum Value { get; }
public string Name { get; }
protected EnumClass(TEnum enumValue)
{
值 = enumValue。
Name = Enum.GetName(typeof(TEnum), enumValue)。
}
public static TEnumClass Parse< TEnumClass>(string name)
where TEnumClass : EnumClass<TEnum>/span>
{
//TODO:/span> try/catch
/* 契約:派生類必須有一個公共建構式。
它需要一個列舉型別的引數。
通用約束不支持帶引數的建構式,所以我們在這里需要反思...... */
return(TEnumClass)Activator.CreateInstance(
typeof(TEnumClass), Enum.Parse(typeof(TEnum), name))。
}
uj5u.com熱心網友回復:
你可以使用一個奇怪的遞回模板模式,但它需要默認的建構式,感覺很奇怪。通常情況下,如果事情變得如此復雜,就應該詢問你的需求是否可以被重組,從而使其不那么復雜,但從給出的細節來看,很難知道這是否可行。也就是說,這可能是你能得到的最接近你所要求的東西了。
沒有辦法指定一個方法回傳派生型別,但是你可以使用通用型別來指定回傳型別。下面是EnumClass,但被修改為接受兩個通用型別。第一個型別是之前的列舉型別,但第二個型別是用來指定派生型別的(因此模板的遞回部分)。
public abstract class EnumClass<。 T, TDerived>
where T : Enum where TDerived : EnumClass<T, TDerived> , new()
{
protected EnumClass()
{
}
protected EnumClass(T enumValue)
{
價值=enumValue。
}
private T _value = default(T)。
public T Value
{
get => _value;
init => _value = value。
}
private string _name = null;
public string Name
{
獲取 獲取
{
_name = _name ? Enum.GetName(typeof(T), Value)。
return _name;
}
}
title">Parse(string name)?
{
var enumValue = (T)Enum.Parse(typeof(T), name);
return new TDerived() {Value = enumValue};
}
那么,使用這個EnumClass的派生型別會是這樣的,其中第二個通用型別遞回地指代它自己,這意味著EnumClass中的靜態Parse方法將回傳一個型別AnimalTypes。
public class AnimalTypes : EnumClass<AnimalTypesEnum, AnimalTypes>
{
public AnimalTypes() 。base()。
{
}
public AnimalTypes(AnimalTypesEnum value>)。base(value)。
{
}
在使用中,它看起來像這樣
//由于我們被要求有公共的默認建構式,所以可以
//有一個 "默認 "的AnimalTypes類,它將類似于構造。
/a "new AnimalTypes(default(AnimalTypesEnum)); "
var defaultType = new AnimalTypes() 。
//this will output "CAT, CAT"
Console.WriteLine($"{defaultType.Value}, {defaultType.Name}")。)
//Since we are using init, you can initialize the value using this format.
//instead of using the constructor[/span].
var horseType = new AnimalTypes() {Value = AnimalTypesEnum.HORSE};
//this will output "HORSE, HORSE"
Console.WriteLine($"{horseType.Value}, {horseType.Name}"/span>) 。
//正常建構式。
var dogType = new AnimalTypes(AnimalTypesEnum.DOG)。
//this will output "DOG, DOG"
Console.WriteLine($"{dogType.Value}, {dogType.Name}") 。
//static決議器將回傳一個AnimalTypes的型別。
var bearType = AnimalTypes.Parse("BEAR")。
//this will output "BEAR, BEAR"
Console.WriteLine($"{bearType.Value}, {bearType.Name}")。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/318608.html
標籤:
上一篇:Java自參考的通用型別
