【发布时间】:2021-12-25 16:45:43
【问题描述】:
4 编辑。我现在意识到我的问题有缺陷,因为我很难解释它,所以它是有道理的。但经过更多阅读后,我发现了这个Statically Typed or Dynamically Typed,其中包含“ ...静态类型语言:
- 每个表达式都是编译时已知的类型。
- 变量仅限于编译时已知的类型”
创建/转换一个只有在运行时才知道的类型的变量基本上是我想知道的是否可以这样做。显然不是。即使我可以在运行时检查类型,我也无法创建该类型的变量。
除非我涉及动态类型并且在具体对象上有预定义的方法来返回自己..
这更像是一个“有可能”的问题,而不是“我需要这样解决它的帮助”...... 我有:
interface IFruit {}
class Apple : IFruit {}
class Pear: IFruit {}
class Banana: IFruit {}
class CuttingBoard
{
public void Cut(Queue<IFruits> fruits)
{
IEnumerable<Type> typesImplementingIFruit = ReflectionHelper.GetAllTypesThatImplementInterface<IFruit >(typeof(IFruit ).Assembly);
while(fruits.Count != 0)
{
var fruit = fruits.Dequeue();
// can I somehow, cast fruit to the concrete class using the typesImplementingIFruit that contains all three concrete types ?
// **2 Edit**, like this:
foreach(var t in typesImplementingIFruit)
{
if(fruit.GetType() == t)
{
var concrete = fruit as t;
break;
}
}
// end of 2 Edit
}
}
}
我尝试了很多不同的概念,使用 TypeConverters 和 Reflection 结合 typesImplementingIFruit 和 IFruit dequeued 中的类型,但没有成功。
This is a similar post 但我看不出在我的情况下如何使用动态和/或作为迈向具体参考的一步会有什么好处。
为了防止它,我知道我可以使用“if (fruit is Apple)”或“switch(fruit) case Apple”,但这是一个不使用实现接口的类型列表的解决方案
1 编辑:
我不想扩展接口、使用抽象或其他有意义的方法,因为这会破坏示例。除非偏离路线,否则有可能获得具体的课程..
这感觉有点相似:reflection to call generic method,但它涉及调用方法而不是强制转换。
我目前的猜测是我的示例无法解决,如果这是答案,我很高兴,因此我可以继续前进:)
3 编辑。
我会尝试重新编码问题。
static void EatApple(Apple apple)
{ }
static void Main(string[] args)
{
object apple = new Apple() { Size = 30 };
EatApple(??apple??);
}
是否有可能在运行时以某种方式将对象变为苹果引用,以便我可以用作EatApple 的参数?
像这样,但在 Apple 中没有 self 方法
class Apple
{
public int Size;
public Apple Self()
{
return this;
}
}
class Program
{
static void EatApple(Apple apple)
{ }
static void Main(string[] args)
{
object apple = new Apple() { Size = 30 };
var sameApple = ((dynamic)apple).Self();
EatApple(sameApple);
}
}
【问题讨论】:
-
您认为如何将一个类型转换为该类型的实例?此外,您的应用程序中可能根本没有这种类型的实例。但是您始终可以通过
Activator.CreateInstance<T>方法创建一个新实例。这符合您的需求吗? -
对不起,但是你为什么不直接在
IFruit上声明东西来从多态性中受益 -
按照@andriy 所指出的,您可以在
IFruit上声明每个水果必须实现的方法或属性(例如bool MustBePeeled { get; })。然后每个水果都会实现它们(例如,香蕉可能有public bool ShouldBePeeled => true;,而其他水果可能返回false。这比在类型上匹配switch更简洁:switch (fruit.GetType()) { case Apple apple: DoSomethingWithApple(apple); break; etc -
如果您可以接受单继承,请将
Fruit设为抽象类,并为您可以对水果执行的各种操作提供默认实现。然后各种水果可以根据需要覆盖它们 -
@Dmitry - 我不知道,但我的感觉是这是不可能的 :) 如果我使用 CreateInstance 我不能选择通用版本(如果我错了,请纠正我),因此会留下一个 Object 类型的实例而不是接口。还是我错过了什么?