【问题标题】:Cast with GetType()使用 GetType() 进行投射
【发布时间】:2009-02-17 03:42:41
【问题描述】:

是否可以将对象转换为从GetType() 返回的类型?我想要一个可以接受对象(对于匿名类型)但然后返回一个对象强制转换为匿名类型的通用方法。我一直在考虑使用 LCG DynamicMethod 在容器类上构建一个方法,但我无法完全弄清楚它会是什么样子。使用GetType() 方法进行转换的想法是能够在不知道类型的情况下获取匿名类型并将对象转换为其实际类型。

总体目标是将匿名类型的对象粘贴到容器中,然后我可以在方法之间共享和传递。

【问题讨论】:

  • 我很好奇你的用例在这里,因为变量类型也不需要正确,动态类型是不可能的。
  • 我猜是通用方法?
  • 这个已经很老了。我最初正在研究使用匿名类型作为存储机制在 C# 中实现教程 D 语言。原来是个坏主意。动态可以改变这一点,但我已经放弃了这个项目......现在。

标签: c# reflection casting


【解决方案1】:

我想不出你为什么要强制转换为 GetType(),因为在编译时不知道类型的情况下,你将无法对结果做任何有用的事情。

也许您正在寻找的是能够转换。如果是这种情况,以下内容应该适合您:

object input = GetSomeInput();
object result = Convert.ChangeType(input, someOtherObject.GetType());

我们在从注册表中读取所有存储为字符串的值时使用它,然后使用反射将它们填充到属性中。

【讨论】:

  • 注意:GetSomeInput() 返回的类型必须实现IConvertible(自顶向下)。我认为内在的 .NET CLR 类型都可以。 ;)
  • 我更改了答案。虽然 convert 很有帮助,但它会返回一个对象。我真正需要的是返回的实际类型。
  • 这是一个有效的用例:从对第三方库的调用中,我们得到一个方法名称、一个 PropertyInfo 和一个始终为 double 的值。由于几个方法的参数是整数,我们的应用程序崩溃了。使用此代码,我们可以将接收到的 double 转换为 ParameterInfo.ParameterType 而不会出现任何问题。谢谢! :)
  • 我现在使用的用例:保存在 RavenDB 中的基本对象类型,但我需要 ASP.net MVC 中 Razor 视图引擎的完整类型。谢谢!
  • 我发现Convert.ChangeType(input, property.PropertyType); 按照这个答案:stackoverflow.com/questions/17703723/… 是我在类似情况下所需要的
【解决方案2】:

你的意图很不明确;但是,一种选择是泛型,尤其是MakeGenericMethod。你想用这个做什么?例如:

static class Program
{
    static void Main()
    {
        object obj = 123.45;
        typeof(Program).GetMethod("DoSomething")
            .MakeGenericMethod(obj.GetType())
            .Invoke(null, new object[] { obj });
    }
    public static void DoSomething<T>(T value)
    {
        T item = value; // well... now what?
    }    
}

所以现在我们有了值,通过泛型输入为double - 但除了调用 other 泛型方法外,我们仍然无能为力...你是什么想在这里做什么?

【讨论】:

    【解决方案3】:

    您可以使用Activator.CreateInstance 方法从一个类型创建一个实例。

    仅供参考,反射是 SLOOWWWW,因此如果您需要连续多次执行此转换,最好在枚举或类似的东西中定义您的类型,然后在不使用反射的情况下创建实例。

    【讨论】:

    • 您如何从存储在枚举中的类型创建实例而不进行反射?
    • C# 枚举不存储类型,具体的枚举是一种类型,该枚举的每个实例化都有一个值。如果你想使用枚举来创建一个类型,那么你应该只使用一个工厂并对其进行硬编码来更新你的类型。
    【解决方案4】:

    我有一个类用于在我的Windows Forms 应用程序中进行更改跟踪,因为并非所有项目都是databound。大多数项目是TextBox 控件,但也有ComboBoxDateTimePicker 控件。

    为简单起见,我的HasChanged 属性测试通用Windows.Forms.Control 以查看它是否是组合框,但您可以测试添加到Windows 窗体的任何类型的控件。

    下面是该课程 - 如果它对任何人都有帮助。

    internal class DataItem
    {
        private static Color originalBackColor, changedBackColor, originalForeColor, changedForeColor;
        private static Font originalFont, changedFont;
    
        static DataItem()
        {
            originalBackColor = SystemColors.Control;
            changedBackColor = SystemColors.HighlightText;
            originalForeColor = Color.Black;
            changedForeColor = Color.Red;
            originalFont = new Font(FontFamily.GenericSansSerif, 12.5f);
            changedFont = new Font(originalFont, FontStyle.Bold);
        }
    
        public static void ChangeSetup(Control original, Color changedBackgroundColor)
        {
            originalBackColor = original.BackColor;
            originalForeColor = original.ForeColor;
            originalFont = original.Font;
            changedBackColor = changedBackgroundColor;
            changedFont = new Font(originalFont, FontStyle.Bold);
        }
    
        private bool changeTracking;
    
        public DataItem(Control control, Object value)
        {
            this.Control = control;
            var current = String.Format("{0}", Control.Text).Trim();
            if (Control is ComboBox)
            {
                var cbo = (ComboBox)Control;
                current = cbo.StateGet();
            }
            this.OriginalValue = current;
            this.Control.TextChanged += Control_TextChanged;
            changeTracking = true;
        }
    
        public Control Control { get; private set; }
    
        private void Control_TextChanged(Object sender, EventArgs e)
        {
            if (TrackingChanges)
            {
                if (HasChanged)
                {
                    this.Control.BackColor = originalBackColor;
                    this.Control.Font = originalFont;
                    this.Control.ForeColor = originalForeColor;
                }
                else
                {
                    this.Control.BackColor = changedBackColor;
                    this.Control.Font = changedFont;
                    this.Control.ForeColor = changedForeColor;
                }
            }
        }
    
        public bool HasChanged
        {
            get
            {
                var current = String.Format("{0}", Control.Text).Trim();
                if (Control is ComboBox)
                {
                    var cbo = (ComboBox)Control;
                    current = cbo.StateGet();
                }
                return !current.Equals(OriginalValue);
            }
        }
    
        public String OriginalValue { get; private set; }
    
        public void Reset()
        {
            changeTracking = false;
            this.OriginalValue = String.Empty;
            this.Control.Text = String.Empty;
            this.Control.BackColor = originalBackColor;
            this.Control.Font = originalFont;
            this.Control.ForeColor = originalForeColor;
        }
        public bool TrackingChanges
        {
            get
            {
                return changeTracking;
            }
        }
    }
    

    【讨论】:

    • 完全披露:上面有一个StateGet 扩展名,不包括在内。
    【解决方案5】:

    您可以使用 getClass() 返回一个 Class 对象,然后使用 Class 对象中的 cast 方法将对象转换为该 Class 类型的对象,如下所示:

    myObj.getClass().cast(myObj)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-25
      • 2013-02-10
      • 2013-05-05
      • 1970-01-01
      相关资源
      最近更新 更多