【问题标题】:Can't Access my Object's Members无法访问我的对象的成员
【发布时间】:2016-05-12 15:07:45
【问题描述】:

错误:'object' 不包含'lp' 的定义并且没有扩展方法>'lp' 可以找到接受'object' 类型的第一个参数(您是否缺少> using 指令或程序集引用?

如果我尝试从我的对象中获取一个值,我会得到这个......

但是当我运行而不试图获取值时,我可以清楚地看到我的对象确实包含 lp...

反序列化的完整代码...

public object Deserialize(Object obj, string path)

        {

            XmlSerializer serializer = new XmlSerializer(obj.GetType());

            StreamReader reader = new StreamReader(path);
            obj = serializer.Deserialize(reader);
            reader.Close();
            return obj;

        }

人物类...

public class Person
    {
        public string name { get; set; }
        public int age { get; set; }

    }

PersonList 类...

public class PersonList

    {
        public List<Person> lp = new List<Person>();


        public void AddPerson(Person p)
        {
            lp.Add(p);
        }
    }

这是我发送到公共类 PersonList 的人员列表的一个实例

{
    public List<Person> lp = new List<Person>();


    public void AddPerson(Person p)
    {
        lp.Add(p);
    }
}.

更新:我之前进行过强制转换,但我将传入大量不同类型的对象,因此需要一个通用的反序列化函数。有没有办法做到这一点? -

【问题讨论】:

  • XmlSerializer.Deserialize() 返回object(它是在泛型不是 .NET 的一部分时引入的)。只需将其转换obj 类型:var obj = (PersonList)serializer.Deserialize(reader); 变量正确包含该类型的实例,但编译器在编译时无法知道它。

标签: c# winforms oop object


【解决方案1】:

您的 obj 变量被声明为对象实例。在反序列化中强制转换:

var obj = (PersonList)serializer.Deserialize(reader);

【讨论】:

  • 感谢您的回复,我以前也是这样做的,但我会传入大量不同类型的对象,因此需要一个通用的反序列化函数。有没有办法做到这一点?
  • 所有不同的对象类型是否都包含属性lp
  • 那么你的代码是正确的(你的反序列化函数)。在调用 Deserialize 之后再进行投射。
【解决方案2】:

您的 obj 具有 object 类型,因此您只能使用 object 类的一般方法。您应该将 obj 转换为您需要的类型。例如:

obj = (PersonList)serializer.Deserialize(reader);
obj = serializer.Deserialize(reader) as PersonLis;

您也可以使用 is 运算符来检查您的 obj 是否属于 PersonList

【讨论】:

    【解决方案3】:

    您更新了您的问题,请求进行泛型转换,而泛型正是您要寻找的。​​p>

    public T Deserialize<T>(T obj, string path)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
    
        StreamReader reader = new StreamReader(path);
        obj = (T)serializer.Deserialize(reader);
        reader.Close();
        return obj;
    }
    

    【讨论】:

    • 我会删除 obj 参数。它的唯一目的是提供类型。然后用户必须手动指定类型。
    【解决方案4】:

    您可以为 XmlSerializer 编写扩展方法以使用通用反序列化:

    public static class Extension
    {
        public static T Deserialize<T>(this XmlSerializer serializer, StreamReader streamReader)
        {
            try
            {
                return (T) serializer.Deserialize(streamReader);
            }
            catch (InvalidCastException)
            {
                return default(T);
            }
        }
    }
    

    然后调用它:

    XmlSerializer serializer = new XmlSerializer(obj.GetType());
    StreamReader reader = new StreamReader(path);
    
    var deserialized = serializer.Deserialize<PersonList>(reader);
    
    reader.Close();
    

    【讨论】:

      猜你喜欢
      • 2018-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-21
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多