1

私は次のクラスを持っています:

public sealed class TaskType
{
    private readonly String name;
    private readonly int value;

    public static readonly TaskType BUG = new TaskType(1, "Bug");
    public static readonly TaskType ISSUE = new TaskType(2, "Issue");
    public static readonly TaskType FEATURE = new TaskType(3, "Feature");
    //more here

    private TaskType(int value, String name)
    {
        this.name = name;
        this.value = value;
    }

    public override string ToString()
    {
        return name;
    }
}

TaskType を値からキャストするにはどうすればよいですか。

int i = 1;
String name = (TaskType)i.ToString(); // this is where i am stuck!

プロパティを反復処理するには Reflection を使用する必要があることはわかっていますが、これはうまくいきません。

たとえば、この関数を使用しようとしましたが、これは機能しません:

private TaskType getTaskType(int id)
{
    PropertyInfo[] properties = typeof(TaskType).GetProperties(BindingFlags.Public | BindingFlags.Static);

    foreach (PropertyInfo property in properties)
    {
        TaskType t = (TaskType)property.GetValue(null, null);
        if (t.ToValue() == id)
            return t;
    }

    return null;
}
4

3 に答える 3

3

列挙型を使用しないのはなぜですか?

public enum Task {
  Bug,
  Issue,
  Feature
}

次に、intからキャストできます。

int i = 1;
Task myTask = (Task)i;

文字列名から取得することもできます。

string s = "Bug";
Task bugType = Enum.Parse(typeof(Task), s);
于 2013-03-04T23:56:27.287 に答える
2

問題は、プロパティを取得しようとしているが、TaskTypeオブジェクトがフィールドであることです:

public static TaskType GetTaskType(int id)
{
    FieldInfo[] fields = typeof(TaskType).GetFields(BindingFlags.Public | BindingFlags.Static);

    foreach (FieldInfo field in fields)
    {
        TaskType t = (TaskType)field.GetValue(null);
        if (t.value == id)
        {
            return t;
        }
    }

    return null;
}

LINQ を使用すると、これは 1 行のコードで済みます。

public static TaskType GetTaskType(int id)
{
    return typeof(TaskType)
        .GetFields(BindingFlags.Public | BindingFlags.Static)
        .Select(f => (f.GetValue(null) as TaskType))
        .FirstOrDefault(t => t != null && t.value == id);
}

public static TaskType GetTaskType(string name)
{
    return typeof(TaskType)
        .GetFields(BindingFlags.Public | BindingFlags.Static)
        .Select(f => (f.GetValue(null) as TaskType))
        .FirstOrDefault(
            t => t != null &&
            t.name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
}

ただし、他の人がすでに述べたように、enumはるかに簡単かもしれません。

于 2013-03-05T01:12:45.350 に答える
1

あなたが本当にそのクラス定義に固執していて、列挙型のようなものを使用できない場合は、リフレクションを介して名前を取得する作業コードを次に示します。

int id = 1;
Type type = typeof(TaskType);
BindingFlags privateInstance = BindingFlags.NonPublic | BindingFlags.Instance;
var name = type
    .GetFields(BindingFlags.Public | BindingFlags.Static)
    .Select(p => p.GetValue(null))
    .Cast<TaskType>()
    .Where(t => (int)type.GetField("value", privateInstance).GetValue(t) == id)
    .Select(t => (string)type.GetField("name", privateInstance).GetValue(t))
    .FirstOrDefault();

// Output: Bug
于 2013-03-05T00:01:44.763 に答える