在单个数组中实现通用接口的多个 类
Multiple classes that implement a generic interface in a single array
假设我有一个通用接口,它存储一个由通用参数键入的值:
public interface IFoo<TValue>
{
TValue SomeValue { get; set; }
}
然后我有两个类、StringFoo
和DoubleFoo
,它们的SomeValues
分别是string
和double
:
public class StringFoo : IFoo<string>
{
string SomeValue { get; set; }
}
public class DoubleFoo : IFoo<double>
{
double SomeValue { get; set; }
}
我现在决定我想要一个可以同时包含 StringFoo
s 和 DoubleFoo
s 的数组:
var foos = IFoo<object>[] {
new StringFoo { SomeValue = "a value" },
new DoubleFoo { SomeValue = 123456789 }
}
我认为,因为 string
和 double
都是 object
的子 类,所以它们都可以出现在这个数组中。然而,我想错了。
所以,我尝试使用协方差:
public interface IFoo<out TValue>
但是,由于接口同时包含 setter 和 getter,我不能这样做。
那么,两个 类 可以在一个数组中实现通用接口吗?
问题可以通过实施 Bar class 的方式解决(也提供了错误的示例)。问题在于,无论何时尝试使用通用接口或 class 实现通用接口代码都可以编译(提供正确的强制转换),但代码将在 运行 时间内抛出 InvalidCastException。
public interface IFoo<TValue>
{
TValue SomeValue { get; set; }
}
public class StringFoo : IFoo<string>
{
public string SomeValue { get; set; }
}
public class DoubleFoo : IFoo<double>
{
public double SomeValue { get; set; }
}
public class Foo<TValue> : IFoo<TValue>
{
public TValue SomeValue { get; set; }
}
public abstract class Bar
{
}
public class Bar<TValue> : Bar, IFoo<TValue>
{
public TValue SomeValue { get; set; }
}
public static class Verify
{
public static void QuestionArray()
{
var foos = new IFoo<object>[]
{
(IFoo<object>) new StringFoo { SomeValue = "a value" },
(IFoo<object>) new DoubleFoo { SomeValue = 123456789 }
};
}
public static void BadAnswerArray()
{
var foo = new IFoo<object>[]
{
(IFoo<object>) new Foo<string>(),
new Foo<object>(),
};
}
public static void GoodAnswer()
{
var foo = new Bar[]
{
new Bar<string>(),
new Bar<object>(),
new Bar<double>()
};
}
}
为了验证解决方案,可以 运行 测试只有 GoodAnswerTest 会通过:
public class GenericsInArrayTests
{
[Fact]
public void QuestionArrayTest()
{
Verify.QuestionArray();
}
[Fact]
public void BadAnswerTest()
{
Verify.BadAnswerArray();
}
[Fact]
public void GoodAnswerTest()
{
Verify.GoodAnswer();
}
}
假设我有一个通用接口,它存储一个由通用参数键入的值:
public interface IFoo<TValue>
{
TValue SomeValue { get; set; }
}
然后我有两个类、StringFoo
和DoubleFoo
,它们的SomeValues
分别是string
和double
:
public class StringFoo : IFoo<string>
{
string SomeValue { get; set; }
}
public class DoubleFoo : IFoo<double>
{
double SomeValue { get; set; }
}
我现在决定我想要一个可以同时包含 StringFoo
s 和 DoubleFoo
s 的数组:
var foos = IFoo<object>[] {
new StringFoo { SomeValue = "a value" },
new DoubleFoo { SomeValue = 123456789 }
}
我认为,因为 string
和 double
都是 object
的子 类,所以它们都可以出现在这个数组中。然而,我想错了。
所以,我尝试使用协方差:
public interface IFoo<out TValue>
但是,由于接口同时包含 setter 和 getter,我不能这样做。
那么,两个 类 可以在一个数组中实现通用接口吗?
问题可以通过实施 Bar class 的方式解决(也提供了错误的示例)。问题在于,无论何时尝试使用通用接口或 class 实现通用接口代码都可以编译(提供正确的强制转换),但代码将在 运行 时间内抛出 InvalidCastException。
public interface IFoo<TValue>
{
TValue SomeValue { get; set; }
}
public class StringFoo : IFoo<string>
{
public string SomeValue { get; set; }
}
public class DoubleFoo : IFoo<double>
{
public double SomeValue { get; set; }
}
public class Foo<TValue> : IFoo<TValue>
{
public TValue SomeValue { get; set; }
}
public abstract class Bar
{
}
public class Bar<TValue> : Bar, IFoo<TValue>
{
public TValue SomeValue { get; set; }
}
public static class Verify
{
public static void QuestionArray()
{
var foos = new IFoo<object>[]
{
(IFoo<object>) new StringFoo { SomeValue = "a value" },
(IFoo<object>) new DoubleFoo { SomeValue = 123456789 }
};
}
public static void BadAnswerArray()
{
var foo = new IFoo<object>[]
{
(IFoo<object>) new Foo<string>(),
new Foo<object>(),
};
}
public static void GoodAnswer()
{
var foo = new Bar[]
{
new Bar<string>(),
new Bar<object>(),
new Bar<double>()
};
}
}
为了验证解决方案,可以 运行 测试只有 GoodAnswerTest 会通过:
public class GenericsInArrayTests
{
[Fact]
public void QuestionArrayTest()
{
Verify.QuestionArray();
}
[Fact]
public void BadAnswerTest()
{
Verify.BadAnswerArray();
}
[Fact]
public void GoodAnswerTest()
{
Verify.GoodAnswer();
}
}