【问题标题】:Nullable.GetUnderlyingType is not Working ProperlyNullable.GetUnderlyingType 工作不正常
【发布时间】:2013-01-22 04:13:14
【问题描述】:

我有以下代码:

Tuple<string, string, Type, ParameterInfo[]> method = (Tuple<string, string, Type, ParameterInfo[]>)(comboBox1.SelectedItem);
if (comboBox2.SelectedIndex - 1 >= 0)
{
    if (method.Item4[comboBox2.SelectedIndex - 1].ParameterType.BaseType == typeof(Enum))
    {
        foreach (object type in Enum.GetValues(method.Item4[comboBox2.SelectedIndex - 1].ParameterType))
        {
            Console.WriteLine(type);
        }
        MessageBox.Show("This looks like an auto-generated type; you shouldn't set it to anything.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
    }
    else if (Nullable.GetUnderlyingType(method.Item4[comboBox2.SelectedIndex - 1].ParameterType) != null)
    {
        if (Nullable.GetUnderlyingType(method.Item4[comboBox2.SelectedIndex - 1].ParameterType).BaseType == typeof(Enum))
        {
            MessageBox.Show("This looks like an auto-generated type; you shouldn't set it to anything.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
        }
    }
}

在 else if 语句中,我注意到它总是返回 null,即使在我的情况下,method.Item4[0] 处的对象在 comboBox2.SelectedIndex 为 1 时始终是 Nullable 类型,那么为什么它返回 null ?说真的,我在那里设置了一个断点,在 Item4 中,我看到索引 0 处的对象为:

[0] = {System.Nullable`1[CarConditionEnum]& carCondition}

...在索引 1 处为:

[1] = {Boolean& carConditionSpecified}

【问题讨论】:

  • 很难从您在此处提供的代码中重现。显然ParameterInfo 显示为{System.Nullable`1[CarConditionEnum]&amp; carCondition} 应该有一个ParameterTypeCarConditionEnum?,所以可以为空。你确定数组的索引是正确的吗?
  • @JeppeStigNielsen - 好吧,如果在第一个 if 语句下我包括这两行: string s1 = method.Item4[comboBox2.SelectedIndex - 1].ParameterType.ToString();字符串 s2 = method.Item4[comboBox2.SelectedIndex - 1].ToString(); ...断点会告诉我 s1 是:s1 = "System.Nullable1[CarConditionEnum]&amp;" ...and s2 is: s2 = "System.Nullable1[CarConditionEnum]& carCondition"
  • 另一个提示:不要说.BaseType == typeof(Enum)(两个地方),你可以简单地使用.IsEnum

标签: c# .net types methods nullable


【解决方案1】:

问题是参数是引用类型,即它被声明为ref CarConditionEnum? paramName

需要获取参数的元素类型,然后使用Nullable.GetUnderlyingType

Type paramType = method.Item4[comboBox2.SelectedIndex - 1].ParameterType;
if(paramType.HasElementType)
{
    paramType = paramType.GetElementType();
}

if(Nullable.GetUnderlyingType(paramType) != null)
{
}

【讨论】:

  • 啊,找不到如何删除该类型的 ByRef“包装”。我没有想到GetElementType()。看起来GetElementType 可用于撤消MakeArrayType()MakePointerType()MakeByRefType()。很高兴知道。
【解决方案2】:

问题在于参数是refout,我可以从与符号&amp; 字符中看到。起初我不知道如何删除它,但事实证明 (the other answer) 你使用了GetElementType()

我这样复制你的发现:

var t1 = typeof(int?);
string s1 = t1.ToString();  // "System.Nullable`1[System.Int32]"
bool b1 = Nullable.GetUnderlyingType(t1) != null;  // true

var t2 = t1.MakeByRefType();
string s2 = t2.ToString();  // "System.Nullable`1[System.Int32]&"
bool b2 = Nullable.GetUnderlyingType(t2) != null;  // false

// remove the ByRef wrapping
var t3 = t2.GetElementType();
string s3 = t3.ToString();  // "System.Nullable`1[System.Int32]" 
bool b3 = Nullable.GetUnderlyingType(t3) != null;  // true

这里,t1t3 是同一类型,ReferenceEquals(t1, t3)

【讨论】:

  • @Servy 我的答案的第一个版本确实包含了为什么原始问题的代码不起作用的正确解释。但我承认这不是很清楚。希望现在更好,现在我从 Lee 的回答中学到了如何摆脱与类型相关的 ByRef 东西。
猜你喜欢
  • 2020-04-23
  • 2023-04-10
  • 2015-01-16
  • 1970-01-01
  • 2016-08-02
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多