假设我在类或方法中有一个泛型成员,所以:
public class Foo<T>
{
public List<T> Bar { get; set; }
public void Baz()
{
// get type of T
}
}
Run Code Online (Sandbox Code Playgroud)
当我实例化类时,T变为MyTypeObject1,所以类具有通用列表属性:List<MyTypeObject1>.这同样适用于非泛型类中的泛型方法:
public class Foo
{
public void Bar<T>()
{
var baz = new List<T>();
// get type of T
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道,我的类列表包含什么类型的对象.所以调用的list属性Bar或局部变量baz包含什么类型的T?
我做不到Bar[0].GetType(),因为列表可能包含零元素.我该怎么做?
使用.NET时,我遇到了一个非常奇怪的问题XmlSerializer.
采用以下示例类:
public class Order
{
public PaymentCollection Payments { get; set; }
//everything else is serializable (including other collections of non-abstract types)
}
public class PaymentCollection : Collection<Payment>
{
}
public abstract class Payment
{
//abstract methods
}
public class BankPayment : Payment
{
//method implementations
}
Run Code Online (Sandbox Code Playgroud)
AFAIK,有三种不同的方法可以解决InvalidOperationException由序列化程序不知道派生类型引起的问题Payment.
1.添加XmlInclude到Payment类定义:
这是不可能的,因为所有类都包含在我无法控制的外部引用中.
2.在创建XmlSerializer实例期间传递派生类型的类型
不行.
3.定义XmlAttributeOverrides目标属性以覆盖属性的默认序列化(如本SO帖子中所述)
也不起作用(XmlAttributeOverrides初始化如下).
Type bankPayment = typeof(BankPayment);
XmlAttributes attributes = …Run Code Online (Sandbox Code Playgroud) 我将简化代码以节省空间,但所呈现的内容确实说明了核心问题.
我有一个类,它有一个基类型的属性.有3个派生类可以分配给该属性.
如果我将任何派生类分配给容器并尝试序列化容器,则XmlSerializer会抛出可怕的:
"不期望类型x.使用XmlInclude或SoapInclude属性指定静态未知的类型."
但是我的基类已经用该属性修饰,所以我认为必须有一个额外的"隐藏"要求.
真正奇怪的是,默认的WCF序列化程序对此类层次结构没有任何问题.
Container类
[DataContract]
[XmlRoot(ElementName = "TRANSACTION", Namespace = Constants.Namespace)]
public class PaymentSummaryRequest : CommandRequest
{
[DataMember]
public PaymentSummary Summary { get; set; }
public PaymentSummaryRequest()
{
Mechanism = CommandMechanism.PaymentSummary;
}
}
Run Code Online (Sandbox Code Playgroud)
基类
[DataContract]
[XmlInclude(typeof(xPaymentSummary))]
[XmlInclude(typeof(yPaymentSummary))]
[XmlInclude(typeof(zPaymentSummary))]
[KnownType(typeof(xPaymentSummary))]
[KnownType(typeof(yPaymentSummary))]
[KnownType(typeof(zPaymentSummary))]
public abstract class PaymentSummary
{
}
Run Code Online (Sandbox Code Playgroud)
派生类之一
[DataContract]
public class xPaymentSummary : PaymentSummary
{
}
Run Code Online (Sandbox Code Playgroud)
序列化代码
var serializer = new XmlSerializer(typeof(PaymentSummaryRequest));
serializer.Serialize(Console.Out,new PaymentSummaryRequest{Summary = new xPaymentSummary{}});
Run Code Online (Sandbox Code Playgroud)
例外
System.InvalidOperationException:生成XML文档时出错.---> System.InvalidOperationException:不期望类型为xPaymentSummary.使用XmlInclude或SoapInclude属性指定静态未知的类型.在
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentSummaryRequest.Write13_PaymentSummary(String n,String ns,PaymentSummary o,Boolean isNullable,Boolean needType)at at …
我认为将该属性添加到接口将有助于确保您不创建使用该接口的类并忘记使它们可序列化.
这可能是一个非常基本的问题,但我想问专家.
我正在尝试使用XmlSerializer来持久化List(T),其中T是一个接口.序列化器不喜欢接口.我很好奇是否有一种简单的方法可以使用XmlSerializer轻松地序列化异构对象列表.这就是我想要的:
public interface IAnimal
{
int Age();
}
public class Dog : IAnimal
{
public int Age()
{
return 1;
}
}
public class Cat : IAnimal
{
public int Age()
{
return 1;
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
var animals = new List<IAnimal>
{
new Dog(),
new Cat()
};
var x = new XmlSerializer(animals.GetType());
var b = new StringBuilder();
var w = XmlTextWriter.Create(b, new XmlWriterSettings { NewLineChars = "\r\n", Indent = true });
//FAIL - …Run Code Online (Sandbox Code Playgroud) 我正在学习Web服务,我正在使用的书是使用实体框架从SQL服务器中提取数据(我对此也知之甚少).
不幸的是,实体框架创建的类包含以下内容:
public Conference()
{
this.Sessions = new HashSet<Session>();
}
public virtual ICollection<Session> Sessions { get; set; }
Run Code Online (Sandbox Code Playgroud)
这导致问题,因为接口不可序列化:
无法序列化System.Collections.Generic.ICollection类型的成员X ...因为它是一个接口.
现在,我可以(并且确实)修改生成的类以使用具体类,但如果我需要重新生成实体,则该更改将被撤消.理想情况下,我可以告诉实体框架生成这样的东西(甚至更好,控制具体类型,以便我可以告诉实体框架如果我想要使用List):
public Conference()
{
this.Sessions = new HashSet<Session>();
}
public virtual HashSet<Session> Sessions { get; set; }
Run Code Online (Sandbox Code Playgroud)
可能吗?如果是这样,怎么样?
使用 CollectAs<> 时使用显式转换来解决错误中的问题
来自 WebMethod 的代码
return client.Cypher
.Match("(person:Person)")
.Where((Person person) => person.Email == username)
.OptionalMatch("(person)-[:SPEAKS]-(language:Language)")
.OptionalMatch("(person)-[:CURRENT_LOCATION]-(country:Country)"
.Return((person, language, country) => new ProfileObject
{
Person = person.As<Person>(),
Language = language.CollectAs<Language>(),
Country = country.CollectAs<Country>()
}).Results.ToList();
Run Code Online (Sandbox Code Playgroud)
来自国家级的代码:
public class Language
{
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
ProfileObject 类的新代码:
public class ProfileObject
{
public Person Person { get; set; }
public IEnumerable<Node<Language>> Language { get; set; }
public IEnumerable<Node<Country>> Country { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
仅当我将 ProfileObject 设置为返回 IEnumerable> …