簡體   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