繁体   English   中英

如何在C#中在不运行时强制转换的情况下实现动态泛型类型返回方法?

[英]How to implement a dynamic generic type return method without casting at runtime in C#?

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

如果您要问,为什么不创建setter和getters? 仅仅是因为我计划拥有50-100个以上的属性,并且我不想为每个属性创建设置方法和获取方法。

[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#时可以获得属性的最接近的方法吗?

我不确定我是否真的喜欢这个主意-但您可以通过使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中有一个名为“ dynamic”的关键字。

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

因此,如果您打算使用5+以上的许多返回类型,建议不要使用这种方法。 这就是为什么我建议使用枚举之类的东西来提示返回哪种类型的原因。

就我而言,我将只处理基本的常见返回类型(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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM