[英]How to implement a dynamic generic type return method without casting at runtime in C#?
Say I want to convert the below implementation in Java to C#, so that I don't have to cast the returned value at runtime, where the casting should already be handled in the get method. 假设我想将Java中的以下实现转换为C#,这样我就不必在运行时强制转换返回的值,该转换应该已经在get方法中进行了处理。
why not create setters and getters, if you ask? 如果您要问,为什么不创建setter和getters? simply because I plan to have 50-100+ attributes and I don't want to create setters and getters for every attributes. 仅仅是因为我计划拥有50-100个以上的属性,并且我不想为每个属性创建设置方法和获取方法。
[c#] - what i want to end up doing in c# [c#]-我最终想在c#中做什么
string name = playerA.getAttribute(Attribute.NAME);
int age = playerA.getAttribute(Attribute.AGE);
Currently I can't unless I cast the returned value to the correct type. 目前,除非将返回的值转换为正确的类型,否则我将无法执行。 But can I do that casting in side the get method before returning? 但是我可以在返回之前在get方法中进行转换吗?
[Java] - anyhow, this is the current java implementation that works without casting [Java]-无论如何,这是当前的Java实现,无需强制转换
//setting attributes
playerA.setAttribute(Attribute.NAME, "Tom");
entityB.setAttribute(Attribute.AGE, 4);
...
//getting the attribute without casting
string name = playerA.getAttribute(PlayerAttribute.NAME);
int age = playerB.getAttribute(PlayerAttribute.AGE);
The method inside a Player/Entity is setup like this to get attributes 像这样设置播放器/实体内部的方法以获得属性
[Java] [Java]
public <E> E getAttribute(Attribute attr){
//atrributeRepository is EnumMap<Attribute, Object>
//how I will get my attribute value type at runtime
Object result = attributeRepositoryMap.get(attr);
//the enumMap will only ever hold these three type for this example
if(result instanceof Boolean){ return (E) (Boolean) result; }
if(result instanceof String){ return (E) (String) result; }
if(result instanceof Integer){ return (E) (Integer) result; }
return null;
//say all checks are in place and null will never be reach
}
The closest I was able to get in c# is this. 我能在C#中获得的最接近的是这个。
[c#] - though I can deal with it, i would like to prevent casting [c#]-尽管我可以处理,但我想防止强制转换
string name = (string) getAttribute<string>(Attribute.NAME);
int age = (int) getAttribute<int>(Attribute.AGE);
the method 方法
public T getAttribute<T>(Attribute attribute){
{
Object result = attributeRepositoryDictionary[attribute];
return (T)result;
}
is this as closest as I can get with c#, where casting is needed for getting attributes? 这是我在使用c#时可以获得属性的最接近的方法吗?
I'm not sure I really like it as an idea - but you could do this by making Attribute
generic: 我不确定我是否真的喜欢这个主意-但您可以通过使Attribute
通用来实现:
public static class Attributes
{
public static Attribute<int> Age = new Attribute<int>("age");
public static Attribute<string> Name = new Attribute<string>("name");
}
public class Attribute<T>
{
public string Key { get; }
public Attribute(string key)
{
Key = key;
}
...
}
Then you can implement your method as: 然后可以将您的方法实现为:
public T GetAttribute<T>(Attribute<T> attribute)
{
// attributeDictionary would be a Dictionary<string, object>
return (T) attributeDictionary[attribute.Key];
}
At that point, type inference will be your friend, so you can just write: 届时,类型推断将是您的朋友,因此您可以编写:
int a = player1.GetAttribute(Attributes.Age);
and it'll be equivalent to: 它等效于:
int a = player1.GetAttribute<int>(Attributes.Age);
I was able to find an alternative solution along with @Jon Skeet, which this was more of what I was looking for (not sure if it is an ideal design though). 我能够与@Jon Skeet一起找到替代解决方案,这比我一直在寻找(虽然不确定这是否是理想的设计)。 Anyhow, little did I know there was a keyword called "dynamic" in cSharp. 无论如何,我几乎不知道cSharp中有一个名为“ dynamic”的关键字。
It allowed my method getAttribute() to return any type at runtime, The only requirement is that you must know the return type. 它允许我的方法getAttribute()在运行时返回任何类型,唯一的要求是您必须知道返回类型。
So I do not recommend using this approach if you plan to work with many return types that are in the 5+. 因此,如果您打算使用5+以上的许多返回类型,建议不要使用这种方法。 That's why I would recommend using something like an enum to give clues on what type will be returned. 这就是为什么我建议使用枚举之类的东西来提示返回哪种类型的原因。
In my case, I will only deal with the basic common return types (int, string, float, bool), so its rather easy to know what type will be returned base on the attribute that is called. 就我而言,我将只处理基本的常见返回类型(int,string,float,bool),因此根据调用的属性很容易知道将返回哪种类型。
class Entity
{
Dictionary<Attribute, Object> attributeRepositoryEnumMap;
...
public dynamic getAttribute(Attribute attribute){
Object result = attributeRepositoryEnumMap[attribute];
return result;
}
}
now I can get return attributes like in the example below without casting 现在我可以像下面的示例一样获得返回属性,而无需强制转换
class MyApp
{
Entity e = new Entity();
e.setAttribute(Attribute.NAME, "Bob");
e.setAttribute(Attribute.AGE, 55);
e.setAttribute(Attrbute.HEIGHT, 5.5f);
string name = e.getAttribute(Attribute.NAME);
int age = e.getAttribute(Attribute.AGE);
float height = e.setAttribute(Attribute.HEIGHT);
}
Not sure how this will all work out for me, but a part of this attempt was to also find an easier work around saving and hydrating my json objects without creating tons of setters and getters. 不确定如何为我解决所有问题,但是这种尝试的一部分是找到一种更轻松的工作来解决我的json对象的保存和水化问题,而不创建大量的setter和getter。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.