我不确定此类代码的用语,但我想知道是否可以在括号后实例化变量,但可以使用反射。
我有一个从XML文件加载的地图。这是(int X,int Y,字符串S)的集合,其中X,Y是某个地形的位置,S是表示地形类型的字符串。我有一个字典可以在字符串和相关类型之间传递;例如,一个键/值对可能是typeof(Tree)的“ Tree”。
当使用反射时,尽管我知道可以用参数实例化,但我唯一的舒适方法是使用Activator.CreateInstance(Type t),即使用空构造函数。
当我对地图进行硬编码时,我最初会像这样实例化(在一些i,j for循环内):
case: "Tree"
world.Add( new Tree(i,j) );
Run Code Online (Sandbox Code Playgroud)
在开始考虑反射和保存文件时,我将其更改为:
world.Add( new Tree() { X = i, Y = j }
Run Code Online (Sandbox Code Playgroud)
但是,我意识到这不适用于反射,因此我必须执行以下操作(Tree继承自Terrain,而字典仅将XML保存数据字符串转换为类型):
Type type = dictionary[dataItem.typeAsString];
Terrain t = (Terrain)Activator.CreateInstance(type);
t.X = i;
t.Y = j;
world.Add(t);
Run Code Online (Sandbox Code Playgroud)
我宁愿使用类似
Type type = dictionary[dataItem.typeAsString];
world.Add((Terrain)Activator.CreateInstance(type) { X = i, Y = j }
Run Code Online (Sandbox Code Playgroud)
有没有这样的捷径?我想我是否可以编辑world.Add取一个X和Y并转换为Terrain来访问这些变量,但我仍然对a)这种{var1 = X,var2 = Y}编程的名称感到好奇b)使用反射时是否存在类似的东西。
有什么区别:
typeof(IInterface).IsAssignableFrom(typeof(Class));
Run Code Online (Sandbox Code Playgroud)
和
typeof(Class) is IInterface
Run Code Online (Sandbox Code Playgroud)
?
编辑:对于上下文,我的函数是这样的:
public static List<T> GetAllInstancesOfType<T>() where T:Entity
{
List<T> l = new List<T>();
if (typeof(IMyInterface).IsAssignableFrom(typeof(T)) //or (typeof(T) is IMyInterface)
foreach(Entity e in List1) if (e is T) l.Add(e as T);
else foreach (Entity e in List2) if (e is T) l.Add(e as T);
return l;
}
Run Code Online (Sandbox Code Playgroud) 我正在为游戏编写一个寻路算法,但试图保持它的通用性,以便它可以在未来的应用程序中使用.
我有一个Node类,它包含X,Y和"PassableType".
NodeGrid类存储一个节点数组,包含它们如何连接的图形信息,然后有一个FindAStarPath()函数,该函数将"PassableTypes"作为参数StartNode,EndNode和params.
我的问题是确定"PassableType"应该具有什么类型.
理想情况下我想要的是能够使用通用枚举 - 即每个游戏定义的限制列表.Node将保存该列表中的单个元素,以说明它是什么路径类型(当前游戏可能使用Path,Grass,Wall等)
因此,当实体尝试路径时,它提供路径查找功能,其类型被视为"可通过".所以男人可以使用
FindAStarPath(CurrentNode, DestinationNode, "Path", "Floor", "Door");
Run Code Online (Sandbox Code Playgroud)
但是汽车可能会使用
FindAStarPath(StartNode, EndNode, "Road");
Run Code Online (Sandbox Code Playgroud)
我的问题是我无法弄清楚如何让NodeGrid采用Generic枚举或等效逻辑.
目前我已经接受了字符串,但这意味着我
每次使用它时都必须编写MyEnum.Road.ToString().
理想情况下,我想做点什么
NodeGrid<MyEnum> CurrentNodeGrid = new NodeGrid<MyEnum>()
Run Code Online (Sandbox Code Playgroud)
然后Nodes会将MyEnum作为passableType,路径寻找函数也是如此,因此每个游戏都有一组不同的tile类型用于路径.
但我不能将NodeGrid定义为:
public class NodeGrid<T> where T:enum
Run Code Online (Sandbox Code Playgroud)
为清楚起见,使用此枚举的唯一部分路径查找功能是这个(包含在Node中):
public bool IsPassable(string[] passableTypes)
{
for (var i = 0; i < passableTypes.Count(); i++)
{
if (this.PassableType == passableTypes[i]) return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
谢谢Haighstrom
以下各项的目的,结果和/或表现(所有类型)是否有任何差异:
Marshal.SizeOf(typeof(T))
Run Code Online (Sandbox Code Playgroud)
和
Marshal.SizeOf(default(T))
Run Code Online (Sandbox Code Playgroud)
?
我正在重新提出一个我刚问过的问题,但是想以更简洁的方式重新提出这个问题,因为我认为这引起了一些混乱.
我有一个基类:RoomObject.我有两个子类:Bed和Table,它继承自RoomObject.
我有一个变量currentObject,它是RoomObject类型,但实际上将持有Bed或Table的实例(RoomObject永远不会实例化).
如何在不知道其完整类型的情况下克隆我的currentObject?
即如果currentObject是一张床,我想用克隆床
currentObject = new Bed(currentObject);
Run Code Online (Sandbox Code Playgroud)
如果currentObject是一个表,我想使用
currentObject = new Table(currentObject);
Run Code Online (Sandbox Code Playgroud)
我可以通过调用Activator.CreateInstance(currentObject.GetType())来使用反射,然后复制我需要的任何属性,但这看起来很混乱.
我有一个我希望在外部扩展的Generic类.
如果我属于这个类MyGenericClass<T>,我可以简单地定义一个类似的方法
public MyReturnType MyMethod()
{
MyReturnType m;
//some code
return m;
}
Run Code Online (Sandbox Code Playgroud)
然后可以像往常一样通过实例调用它 myGenericClass.MyMethod();
但是,我想使用扩展在外部添加此功能.
以下内容无法编译:
public static MyReturnType MyMethod(this MyGenericClass<T> mgc)
{
MyReturnType m;
//some code
return m;
}
Run Code Online (Sandbox Code Playgroud)
因为无法推断出类型T.
以下编译:
public static MyReturnType MyMethod<T>(this MyGenericClass<T> mgc)
{
MyReturnType m;
//some code
return m;
}
Run Code Online (Sandbox Code Playgroud)
但是,这需要我键入myGenericClass.MyMethod<MyT>();,更糟糕的是,MyMethod中的"T"没有约束与MyGenericClass中的"T"相同 - 两个泛型是独立的(并且依赖于两个类使用相同类型的用户)和功能).
我该如何正确申报?
谢谢Haighstrom