gpt4 book ai didi

c# - 为什么这里需要显式转换

转载 作者:行者123 更新时间:2023-11-30 19:35:25 25 4
gpt4 key购买 nike

我正在使用与此类似的工厂:

interface I<T>
{
void Print();
}

class A : I<A>
{
public string Id { get; }
public A(string id) { Id = id; }
public void Print() { Console.WriteLine(Id); }
}

class B : I<B>
{
public int Id { get; }
public B(int id) { Id = id; }
public void Print() { Console.WriteLine(Id); }
}

class Factory
{
public T Create<T>()
where T : I<T>
{
if (typeof(T) == typeof(A))
return (T)(I<T>)new A("A");
else if (typeof(T) == typeof(B))
return (T)(I<T>)new B(2);
else
throw new Exception("Unknown className");
}
}

var sut = new Factory();
sut.Create<A>().Print();
sut.Create<B>().Print();

我不完全明白的是:为什么要双重施法

(T)(I<T>)new A()

有必要吗?编译器知道

new A("A") is I<A>

而且确实知道

new A("A") is T

顺便说一句:我正在使用通用接口(interface),否则

Create<I>()

可以正常编译,但这里不需要。

最佳答案

您的代码说明当 typeof(T) == typeof(A) 时是true , 它保证表达式的类型 new A(...)T 兼容.

虽然这个推理在运行时是正确的,但 C# 编译器不会处理 typeof(T) == typeof(A)作为任何一种“类型保护”。

The compiler knows that new A("A") isI<A>

同意

and actually knows that new A("A") is T

不,它不能。在基于模板的方法中(例如在 C++ 中),“通用”函数按每个 T 编译。在源代码中遇到,然后编译器知道。然而在 .NET 中,泛型是基于运行时的,因此 C# 编译器必须编译适用于任何 T 的代码。遵守约束条件,但除此之外还有具体的T在编译时未知。

如果您想使用编译器“类型保护”并避免显式转换,您可以使用 C# pattern matching 重写您的代码:

public T Create<T>()
where T : I<T>
{
if (typeof(T) == typeof(A) && new A("A") is T retA)
return retA;
else if (typeof(T) == typeof(B) && new B(2) is T retB)
return retB;
else
throw new Exception("Unknown className");
}

关于c# - 为什么这里需要显式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56946123/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com