如何实现一个动态泛型返回方法,而不需要在c#运行时强制转换

本文关键字:不需要 运行时 方法 转换 泛型 实现 何实现 动态 一个 返回 | 更新日期: 2023-09-27 18:04:53

假设我想将下面的Java实现转换为c#,这样我就不必在运行时强制转换返回值,因为强制转换应该已经在get方法中处理了。

为什么不创建setter和getter呢?只是因为我计划有50-100+属性,我不想为每个属性创建setter和getter。

[c#] -我想在c#中结束什么

string name = playerA.getAttribute(Attribute.NAME);
int age = playerA.getAttribute(Attribute.AGE);

目前不能,除非我将返回值转换为正确的类型。但我能在返回之前在get方法中进行强制转换吗?

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

播放器/实体内部的方法是这样设置的,以获取属性
(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
}

我能在c#中得到的最接近的是这个。

[c#] -虽然我可以处理它,但我想防止强制转换

string name = (string) getAttribute<string>(Attribute.NAME);
int age = (int) getAttribute<int>(Attribute.AGE);

的方法
public T getAttribute<T>(Attribute attribute){
{
     Object result = attributeRepositoryDictionary[attribute];
     return (T)result;
}

这是最接近的,我可以得到与c#,在哪里需要获得属性?

如何实现一个动态泛型返回方法,而不需要在c#运行时强制转换

我不确定我是否真的喜欢它作为一个想法-但你可以通过使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;
    }
    ...
}

然后你可以实现你的方法:

public T GetAttribute<T>(Attribute<T> attribute)
{
    // attributeDictionary would be a Dictionary<string, object>
    return (T) attributeDictionary[attribute.Key];
}
在这一点上,类型推断将是您的朋友,所以您可以只写:
int a = player1.GetAttribute(Attributes.Age);

等于:

int a = player1.GetAttribute<int>(Attributes.Age);

我能够找到一个替代的解决方案与@Jon Skeet,这是更多的我正在寻找(不确定这是否是一个理想的设计)。总之,我不知道在cSharp中有一个关键字叫"动态"。

它允许我的方法getAttribute()在运行时返回任何类型,唯一的要求是你必须知道返回类型。

因此,如果您计划使用5+中的许多返回类型,我不建议使用这种方法。这就是为什么我建议使用enum之类的东西来提示返回的类型。

在我的例子中,我将只处理基本的常见返回类型(int, string, float, bool),因此很容易根据调用的属性知道返回什么类型。

class Entity 
{
     Dictionary<Attribute, Object> attributeRepositoryEnumMap;
     ...
     public dynamic getAttribute(Attribute attribute){
         Object result = attributeRepositoryEnumMap[attribute];
         return result;
     }
}

现在我可以像下面的例子一样得到返回属性,而不需要强制转换

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

不确定这将如何为我工作,但这个尝试的一部分是也找到一个更容易的工作围绕保存和水化我的json对象而不创建大量的setter和getter。
相关文章: