简体   繁体   English

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

[英]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.

相关问题 当具有有限类型参数的类的方法返回其自身类型的值时,如何使返回值保持通用(无强制转换)? - How to let the return value remain generic (without casting) when a method of a class with a bounded type parameter returns a value of its own type? Java如何使用可变方法和泛型返回类型实现接口 - Java how to implement interface with a variadic method and generic return type 如何实现具有通用返回类型和通用参数的通用方法? - How can I implement generic method which has generic return type and generic parameter? 有没有一种方法可以编写具有通用/动态返回类型的方法? - Is there a way to write a method with generic/dynamic return type? 如何在没有显式转换的情况下返回泛​​型类型的方法上使用lambdaJ的extract() - How to use lambdaJ's extract() on method returning generic type without explicit casting Java泛型方法类型转换 - Java generic method type casting 如何创建泛型方法以返回泛型类型 - How to create generic method to return generic type 在运行时转换之前检查泛型类型 - Check generic type before casting at runtime 将通用返回类型转换为接口类型 - Casting generic return type to interface type 在将通用Collection传递给旧方法时,如何避免类型转换? - How to avoid type casting while passing generic Collection to legacy method?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM