簡體   English   中英

類中枚舉更改函數返回的最佳實踐

[英]Best practice for an enum in a class changing a return of a function

因此,例如您有一個具有聲音類型的對象,並且基於枚舉,特定函數將根據類型播放不同的聲音

public enum ObjectType{
    Type1,
    Type2,
    Type3
}

public class Object{
    public ObjectType type;
    public Sound sound;

    private void DoThing(){

        if(type == ObjectType.Type1){
            sound = Load("sounds/sound1");
        }
        if(type == ObjectType.Type2){
            sound = Load("sounds/sound2");
        }
        //etc...

    }

}

我想我的問題是,當這個枚舉的大小增加到數十或數百時,組織和測試枚舉以返回另一個值的最佳實踐是什么?
我應該使用 switch case 而不是一堆 if 測試嗎? 主要只是關於組織,這些功能並不是真正的資源繁重,也不會使用大量計算,因此性能並不是我真正關心的問題,主要是可讀性。

如果您有數百個值,枚舉可能不是最好的表示,但一般來說,如果您有很多項目需要根據某個值獲取,您將構建一個查找表。

您可以構建該表一次,然后只需一行代碼即可根據相關枚舉值獲取正確的項目。

public class MyObject
{
    private ObjectType type;
    private Sound sound;

    private static Dictionary<ObjectType, Sound> soundLookup = new Dictionary<ObjectType, Sound>()
    {
        { ObjectType.Type1, Load("sounds/sound1") },
        { ObjectType.Type2, Load("sounds/sound2") },
        { ObjectType.Type3, Load("sounds/sound3") },
        // etc.
        { ObjectType.Type99, Load("sounds/sound99") },
    };

    public MyObject(ObjectType objectType)
    {
        this.type = objectType;
        this.sound = soundLookup[objectType];
    }

    private void DoThing()
    {
        var sound = this.sound;
        
        // Do something with sound.
    }

    private static Sound Load(string soundPath)
    {
        return new Sound();
    }
}

如果您能夠對聲音文件和ObjectTypes進行命名約定,那么這將成為模式匹配問題。 例如,如果您將枚舉定義為:

public enum ObjectType
{
    Type1 = 1,
    Type2 = 2,
    Type3 = 3
}

然后你可以用以下方法替換你的方法:

sound = Load($"sounds/sound{(int)type}");

上面一行的哪個(例如,類型是Type1 )會找到“sound1”

如果您無法使用枚舉設置值,但名稱中仍有數字,您可以通過以下方式檢索這些數字:

// Call to replace to get the number, and not the "Type" prefix
string number = Enum.GetName(typeof(ObjectType), type).Replace("Type", "");

有以下用法:

sound = Load($"sounds/sound{number}");

編輯:完整示例

public enum ObjectType{
    Type1,
    Type2,
    Type3
}

public class Object{
    public ObjectType type;
    public Sound sound;

    private void DoThing(){
        string number = Enum.GetName(typeof(ObjectType), type).Replace("Type", "");
        sound = Load($"sounds/sound{number}");    
    }    
}

為了使額外的元數據與枚舉定義保持一致,您可以基於自定義屬性構建一個字典。

public SoundAttribute : Attribute {
    public string File { get; set; }
}

public enum ObjectType{
    [Sound(File = "sound1")]
    Type1,

    [Sound(File = "sound2")]
    Type2,

    [Sound(File = "sound3")]
    Type3
}

public static Dictionary<ObjectType, SoundAttribute> Sounds = 
    typeof(ObjectType)
    .GetFields(BindingFlags.Static | BindingFlags.Public)
    .ToDictionary(
        f => (ObjectType)f.GetValue(null), 
        f => f.GetCustomAttribute<SoundAttribute>()
    );

這是我試圖完成的更深入的實現。
我認為它至少比我試圖做的 switch 方法要好,但我仍然試圖找出那個枚舉。

無論在實例化之前如何手動設置對象類型,每次手動創建新對象類型時都會填充下拉列表,所以我認為枚舉仍然是最好的用途,但我可能是錯的。

    public class MyObject
    {
        public ObjectType type;
        public string soundPath;
        public string otherSoundPath;
        public Sound sound;
        public Sound otherSound;
     
        private void Start()
        {
            type = Self.type;
            soundPath = GetSoundPath(type, false);
            otherSoundPath = GetSoundPath(type, true);
            sound = Load($"\\sounds\\{soundPath}");
            otherSound = Load($"\\sounds\\{otherSoundPath}");
        }
     
        public string GetSoundPath(ObjectType type, bool isOtherClip)
        {
            string soundPath = string.Empty;
            if (!isOtherClip)
            {
                if (!sounds.TryGetValue(type, out soundPath))
                {
                    soundPath = "defaultClip";
                }
            }
            else
            {
                if (!otherSounds.TryGetValue(type, out soundPath))
                {
                    soundPath = "defaultOtherClip";
                }
            }
            return soundPath;
        }
     
        private Dictionary<ObjectType, string> sounds = new Dictionary<ObjectType, string>
        {
            { ObjectType.A, "a" },
            { ObjectType.B, "b" },
            { ObjectType.C, "c" },
        };
     
        private Dictionary<ObjectType, string> otherSounds = new Dictionary<ObjectType, string>
        {
            { ObjectType.A, "a" },
            { ObjectType.B, "b" },
            { ObjectType.C, "c" },
        };
     
    }
     
    public enum ObjectType
    {
        A,
        B,
        C
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM