C#将对象转换为类型参数为

时间:2016-09-07 19:38:41

标签: c# casting

我有一个名为Property的类,它存储一个值并在值发生变化时引发一个事件。有一个名为Observable的不同类我想要包含一个属性字典,我在下面有一个例子。如何获取存储在字典中的属性类型以便我可以修改对象?

物业类别:

public class Property<T>
{
     public T Value { get; set; }
}

可观察类:

public class Observable
{
    public readonly Dictionary<string, object> 
              Properties = new Dictionary<string, object>();

    public Property<T> Get<T>(string name)
    {
        object obj;
        Properties.TryGetValue(name, out obj);
        return (Property<T>) obj;
    }
}

编辑这是我得到的错误 - 未处理的异常:System.InvalidCastException:无法将类型为'System.String'的对象强制转换为'ConsoleApplication.Property`1 [System.String]'。

另外,如果我可以摆脱Get函数并将其替换为不需要知道更好的类型的东西。

更新:有没有办法通过使用类型散列名称来获取类型?

2 个答案:

答案 0 :(得分:2)

编辑(更新后的帖子):

  

有没有办法通过使用类型哈希名称来获取类型?

你想要的是这样的吗? dotnetfiddle link

public interface IProperty
{
    object Value { get; }
    Type TypeOfValue { get; }
}

public class Property : IProperty
{
    public object Value { get; set; }
    public Type TypeOfValue { get; set; }
    public override string ToString() { return TypeOfValue.FullName + ": " + Value; }
}

public class Observable
{
    public readonly Dictionary<string, Property> 
        Properties = new Dictionary<string, Property>();

    // use interface so consumer of your property can't mess with the
    // type or value stored in your dictionary within Observable
    public IProperty Get(string name)
    {
        Property obj;
        if (Properties.TryGetValue(name, out obj)){
            return obj;
        }

        // throw something which makes more sense to you
        throw new ArgumentException(name + " does not exist in the dictionary");
    }

    // sample of how you'd store these properties
    public void Set(string name, object val)
    {
        if (Properties.ContainsKey(name)){
            Properties[name].Value = val;
            Properties[name].TypeOfValue = val.GetType();
        } else {
            Properties[name] = new Property {
                Value = val,
                TypeOfValue = val.GetType()
            };
        }
    }
}

原始回答:

您可能会意外地将string插入Observable内的词典而不是Property<string>,如果是这样,问题就不在您的代码中了已发布,而是在您插入string而不是Property<string>的任何地方。

如果您不喜欢无效的强制转换异常,请使用两种解决方案。

解决方案1:自定义函数抛出的错误。

如果您想保留Get<T>(...)的签名,我建议您进行一些错误处理。您看到的错误是因为字典中的属性类型为string,而不是Property<string>类型。以下代码将为您提供更多错误处理方法。

public class Observable
{
    public readonly Dictionary<string, object> 
        Properties = new Dictionary<string, object>();

    public Property<T> Get<T>(string name)
    {
        object obj;
        if (Properties.TryGetValue(name, out obj)){
            try {
                return (Property<T>) obj;
            } catch(InvalidCastException){
                // throw something which makes more sense to you
                throw new ArgumentException("Could not cast the given object to the desired type");
            }
        }

        // throw something which makes more sense to you
        throw new ArgumentException(name + " does not exist in the dictionary");
    }
}

解决方案2:返回一般object

public class Observable
{
    public readonly Dictionary<string, object> 
        Properties = new Dictionary<string, object>();

    public object Get(string name)
    {
        object obj;
        if (Properties.TryGetValue(name, out obj)){
            return obj;
        }

        // or do whatever you want when the given key doesn't exist.
        return null;
    }
}

答案 1 :(得分:0)

索引器可以在不使用其他构造的情况下解决您的问题。 看看你是否我不确定我是否让你清楚,但我会尽力帮助你 至于我,问题可以改写如下。 是否可以确定最具特定类型的上传类型。

这是一个可以帮助您的代码

 public class Employee
{
    public int salary { get; set; }

}

public class Manager : Employee
{

}

class Program
{
    static void Main(string[] args)
    {
        Manager man = new Manager();
        System.Object emp = (object) man;
        Console.WriteLine(emp.GetType());
    }
}

WriteLine操作的输出是“Project_Name”.Manager,因此您可以看到最初在内存中分配的类型。不熟悉他们。