开发者

Without enums, what alternative to a <string, TValue> Dictionary can yield compile-time errors?

First, I apologize for my lack of knowledge, about how to make this relevant to many people (many neophytes, anyway) - my only programming experience is with Unity. Not that Unity, which I just heard about while searching this site.

I want to know if there's a better data structure than a class, for this sort of thing:

class Cameras {
    public Camera left, right; 
} Cameras cameras;

I find myself creating a bunch of classes (they're not all containers for only two objects), which seem like they would be better served by a Dictionary - except, I want have compile-time errors if I screw up spelling, which won't happen with strings as a key. I also don't want to just use arrays or lists, because I don't want to have to remember what int goes with what object. I could create enums for each class like this, and switch to Dictionaries instead of classes, but that sounds ridicul开发者_如何学Pythonous to me(*). Is there some alternative? It seems to me that what I need is a structure that lets me define something like an enum that gets associated with an Array or List, but I bet you'll have a better idea. ;-)

(*) And yet, from the information you all have provided, that's apparently the model that exists. This seems like a fundamental issue to have addressed, to me, and I wonder why it hasn't been. I don't know if the syntax below has been used for something else, but it seems reasonable to me.

public class StereoCameraSystem : MonoBehaviour {
    // You populate cameras in the Unity Editor GUI.
    // Have the language implement something like this...
    [SerializeField] Camera [] {left, right} cameras;

    // define StereoCameraSide enum here

    void ListCameras () {
        Debug.Log(cameras[left]);  // ...so you can use this...
        Debug.Log(cameras[StereoCameraSide.Left]);  //...and avoid this.
    }
}


Dictionaries don't have to be indexed by strings. You can have a Dictionary<MyEnum, MyClass>, and index by enum. You'll then get full compiler error checking if you mistype the enum identifier when looking something up in the dictionary.


enum CameraKind {
    Left,
    Right
}

var cameras = new Dictionary<CameraKind, Camera> {
    { CameraKind.Left, leftCamera }, // shortcut for Add method
    { CameraKind.Right, rightCamera }
};

DoSomethingWith (cameras [CameraKind.Left]);


If you want to write clean and readable C# code, then you just have to write a lot of (sometimes long) class declarations. This is the way object-oriented programming works.

An alternative solution for your problem - if you're happy to sacrifice some readability - is to use tuples. Tuples are data structures that group two (or more) things with possibly different types in a safe way. To represent two cameras, you could write:

// Wrap two cameras into tuple data structure
Tuple<Camera, Camera> cameras = Tuple.Create(firstCamera, secondCamera);

// Get the first camera
cameras.Item1
// Get the second camera
cameras.Item2

The only unfortunate thing is that you'll have to use Item1 and Item2 instead of nice names (like Left and Right). Tuples come from functional programming, which often gives you a lighter programming style - if you want, you can check out F#, which is a functional language for .NET.


In C# 4.0 it should look like this (note that it has no intellisense support):

dynamic cameras = new ExpandoObject();
cameras.left = new Camera(); // set the property to initialize it
Debug.Log(cameras.left);


Swift's tuples solved the problem. C# will have to alter its tuples to be like Swift's, before it is a viable language to use, when this feature is needed.

let cameras: (left: Camera, right: Camera)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜