I have a system where every interface/class has two codes (InterfaceCode
, SubtypeCode
) - this is for efficiently saving and re-generating objects from hex-strings.
I now have a specific usecase where I need a specific object of a class which inherites Iitem
.
To check if the ItemCode matches the required interface/class I wanted to compare values with T.InterfaceCode
and T.SubtypeCode
(see below). Sadly this won't work because I cannot access members of a type parameter (CS0704
).
public static T AsType<T>(string ItemCode) where T : Iitem
{
if (ItemCode.Length < 5) return null;
ItemCodeDes itemCode = new ItemCodeDes(ItemCode);
if(itemCode.InterfaceCode != T.InterfaceCode) return null; //Error CS0704 Cannot do non-virtual member lookup in 'T' because it is a type parameter
if(itemCode.SubtypeCode != T.SubtypeCode) return null; //same here...
//...
}
with
public static ushort SubtypeCode { get; } = 0;
public static ushort InterfaceCode { get; } = 0;
I really don't wont to hardcode Lookup Tables for each class (there will be about 100-200).
Is there a good & clean solution to my problem (without using Reflection)?
Edit: I am still using C# .NET Core 3.1
For those who need more context:
public class Iitem
{
public static ushort SubtypeCode { get; } = 0;
public static ushort InterfaceCode { get; } = 0;
public Iitem(string itemName, string description, ItemTier tier, ushort id)
{
Name = itemName;
Tier = tier;
Description = description;
Id = id;
}
public string Name { get; }
public string Description { get; }
public ItemTier Tier { get; }
public ushort Id { get; }
/// <summary>
/// Gibt den itemspezifischen Code zurück.
/// </summary>
/// <returns>Itemcode als Hex-String</returns>
public virtual string GetItemCode()
{
return GenerateItemCode(0, 0);
}
internal string GenerateItemCode(ushort Interface, ushort Subtype, ulong Generationspecifics = 0)
{
return Interface.ToString("X1") + Subtype.ToString("X1") + Id.ToString("X3") + (Generationspecifics != 0 ? Generationspecifics.ToString("X") : "");
}
/// <summary>
/// Generiert einen String mit den Stats und einer Beschreibung des Items.
/// </summary>
/// <returns></returns>
public virtual string PrintItem()
{
return Name + " (" + Tier.ToString() + ") - " + Description;
}
public enum ItemTier
{
Common,
Uncommon,
Epic,
Legendary,
Heavengrade,
Forbidden,
}
}
private class ItemCodeDes
{
public ItemCodeDes(string ItemCode)
{
if (ItemCode.Length < 5) return;
InterfaceCode = ushort.Parse(ItemCode[0].ToString(), System.Globalization.NumberStyles.HexNumber);
SubtypeCode = ushort.Parse(ItemCode[1].ToString(), System.Globalization.NumberStyles.HexNumber);
ItemId = ushort.Parse(ItemCode.Substring(2, 3), System.Globalization.NumberStyles.HexNumber);
if (ItemCode.Length > 5)
Generationspecifics = ItemCode.Substring(5);
}
public ushort InterfaceCode { get; }
public ushort SubtypeCode { get; }
public ushort ItemId { get; }
public string Generationspecifics { get; } = "";
}