- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
所以有错误。
InvalidOperationException: The type of the argument object 'Scratch' is not primitive
我正在做的是序列化一个类列表 ( List<BaseEnemy>
)。 BaseEnemy 类也有一个类列表 ( List<BaseMoves>
)。当我运行时,BaseEnemy 列表会正确序列化。但是,BaseMoves 列表没有。 Scratch
是一个派生自存储在 List<BaseMove>
中的 BaseMove 的类.
是我遇到的问题。我在这里找到了答案... HERE ...
"Mark BaseMove class with XmlInclude attribute passing your derived class as parameter:"
[XmlInclude(typeof(Scratch))]
public class BaseMove
{
public BaseMove()
{
}
}
工作起来很有魅力!那我为什么要在这里发帖呢?新问题。我有 HUNDREDS 个源自 BaseMove 的 Action 。有快捷方式还是我必须在 XmlInclude 中编写每个“typeof(...)”?
编辑 - 我找到的另一个解决方案。
public static Type[] GetAllSubTypes(Type aBaseClass)
{
List<Type> result = new List<Type>();
Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly a in assemblies)
{
Type[] types = a.GetTypes();
foreach (Type t in types)
{
if (t.IsSubclassOf(aBaseClass))
result.Add(t);
}
}
return result.ToArray();
}
然后在序列化期间,我只是调用此函数以用作 extraTypes 的数组。
Type[] extraTypes = GetAllSubTypes(typeof(BaseMove));
XmlSerializer xml = new XmlSerializer(typeof(List<BaseEnemy>), extraTypes);
最佳答案
您可以遍历应用程序域中的所有程序集,从您的基类型中找到所有可分配的类型,并在构造您的 XmlSerializer
时将它们作为已知类型传递。但是,一些注意事项:
XmlSerializer
构建后,必须缓存在哈希表或字典中并重复使用以防止内存和资源泄漏。参见 here了解详情。因此,你可以这样做:
public static class XmlSerializerWithKnownTypeCreator<T>
{
static Dictionary<HashSet<Type>, XmlSerializer> table = new Dictionary<HashSet<Type>, XmlSerializer>(HashSet<Type>.CreateSetComparer());
public static XmlSerializer CreateKnownTypeSerializer<TRoot>()
{
return CreateKnownTypeSerializer(new Type [] {typeof(TRoot)});
}
public static XmlSerializer CreateKnownTypeSerializer(IEnumerable<Type> baseTypes)
{
var set = new HashSet<Type>(
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(t => baseTypes.Any(baseType => baseType.IsAssignableFrom(t))));
lock (table)
{
XmlSerializer serializer;
if (table.TryGetValue(set, out serializer))
return serializer;
table[set] = serializer = new XmlSerializer(typeof(T), set.ToArray());
return serializer;
}
}
}
然后这样调用它:
var serializer = XmlSerializerWithKnownTypeCreator<DocumentRoot>.CreateKnownTypeSerializer<BaseMove>();
例如,
var serializer = XmlSerializerWithKnownTypeCreator<List<BaseClass>>.CreateKnownTypeSerializer<BaseMove>();
更新
如果序列化器的参数化通用静态表看起来很奇怪(公平地说,确实有点奇怪),您可以将序列化器存储在非通用全局哈希表中,如 documentation 中所建议的那样:
If you use any of the other constructors, multiple versions of the same assembly are generated and never unloaded, which results in a memory leak and poor performance. The easiest solution is to use one of the previously mentioned two constructors. Otherwise, you must cache the assemblies in a Hashtable, as shown in the following example.
但是,该文档掩盖了如何为 XmlSerializer
生成 key 。代码示例也不是线程安全的,也许是因为所有这些东西都可以追溯到 .Net 1.0。所以这里有一些逻辑可以在全局哈希表中正确地键入和回收具有已知额外类型的 XmlSerializer
:
public abstract class XmlserializerKey
{
readonly Type serializerType;
public XmlserializerKey(Type serializerType)
{
this.serializerType = serializerType;
}
protected Type SerializerType { get { return serializerType; } }
public override bool Equals(object obj)
{
if (ReferenceEquals(this, obj))
return true;
else if (ReferenceEquals(null, obj))
return false;
if (GetType() != obj.GetType())
return false;
XmlserializerKey other = (XmlserializerKey)obj;
if (other.serializerType != serializerType)
return false;
return true;
}
public override int GetHashCode()
{
int code = 0;
if (serializerType != null)
code ^= serializerType.GetHashCode();
return code;
}
public override string ToString()
{
return string.Format("Serializer type: " + serializerType.ToString());
}
}
public abstract class XmlserializerKeyWithExtraTypes : XmlserializerKey
{
static IEqualityComparer<HashSet<Type>> comparer;
readonly HashSet<Type> moreTypes = new HashSet<Type>();
static XmlserializerKeyWithExtraTypes()
{
comparer = HashSet<Type>.CreateSetComparer();
}
public XmlserializerKeyWithExtraTypes(Type serializerType, IEnumerable<Type> extraTypes)
: base(serializerType)
{
if (extraTypes != null)
foreach (var type in extraTypes)
moreTypes.Add(type);
}
protected Type[] MoreTypes { get { return moreTypes.ToArray(); } }
public override bool Equals(object obj)
{
if (!base.Equals(obj))
return false;
XmlserializerKeyWithExtraTypes other = (XmlserializerKeyWithExtraTypes)obj;
return comparer.Equals(moreTypes, other.moreTypes);
}
public override int GetHashCode()
{
int code = base.GetHashCode();
if (moreTypes != null)
code ^= comparer.GetHashCode(moreTypes);
return code;
}
}
public sealed class XmlSerializerKeyWithKnownTypes : XmlserializerKeyWithExtraTypes
{
public XmlSerializerKeyWithKnownTypes(Type serializerType, IEnumerable<Type> otherTypes)
: base(serializerType, otherTypes)
{
}
public XmlSerializer CreateSerializer()
{
return new XmlSerializer(SerializerType, MoreTypes);
}
}
public static class XmlSerializerHashTable
{
static Dictionary<object, XmlSerializer> dict;
static XmlSerializerHashTable()
{
dict = new Dictionary<object, XmlSerializer>();
}
public static XmlSerializer DemandSerializer(object key, Func<object, XmlSerializer> factory)
{
lock (dict)
{
XmlSerializer value;
if (!dict.TryGetValue(key, out value))
dict[key] = value = factory(key);
return value;
}
}
}
public static class XmlSerializerWithKnownDerivedTypesCreator
{
public static XmlSerializer CreateKnownTypeSerializer(Type type, IEnumerable<Type> extraTypes)
{
var allExtraTypes =
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(t => extraTypes.Any(extraType => extraType.IsAssignableFrom(t)));
var key = new XmlSerializerKeyWithKnownTypes(type, allExtraTypes);
return XmlSerializerHashTable.DemandSerializer(key, k => ((XmlSerializerKeyWithKnownTypes)k).CreateSerializer());
}
}
然后以与调用等效的 XmlSerializer
相同的方式调用它构造函数:
public static void Test2()
{
List<BaseClass> list = new List<BaseClass>();
list.Add(new BaseClass());
list.Add(new MidClass());
list.Add(new DerivedClass1());
list.Add(new DerivedClass2());
var serializer = XmlSerializerWithKnownDerivedTypesCreator.CreateKnownTypeSerializer(list.GetType(), new Type[] { typeof(BaseClass) });
string xml = XmlSerializationHelper.GetXml(list, serializer, false);
Debug.WriteLine(xml);
// No assert below:
Debug.Assert(object.ReferenceEquals(serializer, XmlSerializerWithKnownDerivedTypesCreator.CreateKnownTypeSerializer(list.GetType(), new Type[] { typeof(BaseClass) })));
}
关于c# - 无效操作异常 : The type of the argument object 'Scratch' is not primitive,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27391485/
互联网上到处都是他们创建云变量的示例/教程。但是当我创建一个变量(我使用了scratch 2和3)时,我得到了 但我想得到的是: 我刚刚看了一个 youtube 教程,其中被告知要使云正常工作,您必须
我正在使用 Scratch 1.4 为 child 准备类(class)。 本类(class)是关于控制真实设备(自制交通信号灯、 retrofit 有电机、传感器等的玩具) 为了连接硬件,我使用远程
我正在和我的 child 一起阅读一本“用 Scratch 学习编程”的书。其中一项练习是要求创建一个使用一些简单公式的“功能块”。他们没有在书中解释什么是“功能块”,否则我可能会错过。我也找不到任何
我需要构建 Scratch 中使用的编程 block 的迷你版或稍后!或开放 block 。 它们中的代码都很大而且很难理解,尤其是在 Scratch 中,它是用 SmallTalk 的某种子集编写的
我想知道是否有一种简单的方法可以打开一个 .txt 文件并将一些逗号分隔的数据加载到 Scratch 中的变量中,然后将一些变量数据从 Scratch 添加到一个 .txt 文件或类似文件中? 我已经
我儿子对 ROT-13 密码感兴趣。我想帮助他在 MIT Scratch 中编写一个程序,该程序可以将字符串作为输入并返回 ROT-13 编码的文本作为输出。为此,程序需要取出字符串,分离出所有字符,
在 Scratch 2.0 中,添加了对自定义堆栈 block (procedures) 的支持。但是有什么方法可以使用它来“抽象掉”返回值的逻辑吗? 例如,我这里有一个简单计算指数的脚本:( vie
我有一个 multiplayer project它有一些永远的循环,其中包含检查代码。 问题是,由于变量 dvotes、uvotes 滞后,多台计算机可能会处理此问题并更改 crabx 或 craby
我可以阻止某个脚本中的代码在另一个脚本中运行吗?我知道有一个停止 block ,但您只能停止当前脚本、所有其他脚本或所有脚本。 最佳答案 这里有一个解决方法:创建另一个隐藏的 Sprite ,其中只有
我正在为 MIT Scratch 中的教育编写一个简单的游戏,并想让一个 Sprite 转向另一个 Sprite (想想我们的英雄飞船后面的一艘外星飞船)。我可以轻松地让外星飞船指向英雄: point
我尝试从头开始编写Bridson 的泊松圆盘采样算法,它似乎是一些副作用或我找不到的错误。你能帮帮我吗? 这是我的尝试: My try online. Some explanation on the
在我的小狗沙龙项目中,我在到达项链部分时遇到了问题。我希望所有未使用的项链在收到消息 m11 时消失,但保留小狗身上的项链。然而,现在所有的项链都不见了。 这是将项链分配给小狗时运行的代码: 这会将它
我希望我的学生使用 Scratch 的衍生产品 Enchanting 对 Mindstorm NXT 机器人进行编程,以驱动预先编程的类(class),沿着路线行驶并避开障碍物。 (二态、五态和比例线
Error Image 我的一位学生正在 Mac 上使用 IntelliJ 中的处理。我们使用与我在 PC 上使用的相同步骤进行设置(适用于我的 PC),但现在它给我一个错误,指出文件名应该是 Scr
大家好,我是IT共享者,人称皮皮。 前言 Scratch作为少儿编程的首选编程语言,这几年发展的如火如荼,当然,这主要还是因为它简单易学,不用掌握太多概念即可编程,这意味着你不用认识英文单词
我有这个代码: 但是每当 shoot 消息被发送到 bullet Sprite ,并且舞台上有一个克隆人还没有击中它的目标时,克隆人就会与 go to x: (xOfTower) y: (yOfTow
我正在从头开始创建一个迷你家庭游戏,我使用随机选择块在 1 到 27 之间进行选择。我有 27 个背景,上面写着 1 到 27 个数字。但是我注意到在大约 21-22 个数字之后,随机选择器无法选择任
我注意到永远(或重复())循环在迭代之间需要时间(没有“等待()秒”块)。这究竟是多久? 最佳答案 使用此代码进行测试: 每次迭代平均为 0.000000994 秒,因此在处理时间之外似乎没有故意延迟
我的目标是构建 5x5 的图像网格。在以下代码中,row、col 和 rowcol 被创建为 Sprite 的本地变量,以及 newcol, newrow 和 cats 是全局的。 (顺便问一下,是否
我正在 Scratch 上制作一个桨球游戏(只是为了好玩),但我的计分遇到了问题。如果你想看我已经写的代码,游戏链接是https://scratch.mit.edu/projects/66541388
我是一名优秀的程序员,十分优秀!