相关疑难解决方法(0)

C#方差问题:将List <Derived>分配为List <Base>

请看以下示例(部分取自MSDN博客):

class Animal { }
class Giraffe : Animal { }

static void Main(string[] args)
{
    // Array assignment works, but...
    Animal[] animals = new Giraffe[10]; 

    // implicit...
    List<Animal> animalsList = new List<Giraffe>();

    // ...and explicit casting fails
    List<Animal> animalsList2 = (List<Animal>) new List<Giraffe>();
}
Run Code Online (Sandbox Code Playgroud)

这是一个协方差问题吗?这将在未来的C#版本中得到支持吗?是否有任何聪明的解决方法(仅使用.NET 2.0)?

c# covariance

54
推荐指数
4
解决办法
2万
查看次数

c#中的协方差

是否有可能投下List<Subclass>List<Superclass>在C#4.0?

这些方面的东西:

class joe : human {}

List<joe> joes = GetJoes();

List<human> humanJoes = joes;
Run Code Online (Sandbox Code Playgroud)

这不是协方差的意思吗?

如果你能做到:

human h = joe1 as human;
Run Code Online (Sandbox Code Playgroud)

你为什么不能这样做

List<human> humans = joes as List<human>; 
Run Code Online (Sandbox Code Playgroud)

因为那个项目已经被贬低了,所以做人类[0]是不合法的,每个人都会很高兴.现在唯一的选择是创建一个新的List

c# casting covariance

19
推荐指数
2
解决办法
2141
查看次数

通用集合中的多态类型参数

为什么C#编译器不允许泛型集合中的多态类型(T)参数(即List [T])?

以"A"和"B"为例,其中"B"是"A"的子类

class A { }
class B : A { }
Run Code Online (Sandbox Code Playgroud)

并考虑一个带有'A'类型列表的函数

void f(List<A> aL) { }
Run Code Online (Sandbox Code Playgroud)

用"B"类型的列表调用

List<B> bL = new List<B>();

f(bL);
Run Code Online (Sandbox Code Playgroud)

给出以下错误

ERROR: cannot convert from List<B> to List<A>
Run Code Online (Sandbox Code Playgroud)

违反了什么语义规则?

除此之外,还有一个"优雅"的意思,除了循环和铸造每个元素(我想要一些糖)?谢谢.

c# generics

11
推荐指数
2
解决办法
4072
查看次数

将Generic <Derived>转换为Generic <Base>

我有一个基础WPF UserControl,它处理派生UserControls的一些常用功能.在任何派生的UserControl的代码隐藏中,我调用一个事件

private void SomeClick(object sender, RoutedEventArgs e) {
    HandleClick(sender);
    MyDataGrid.Items.Refresh();
}
Run Code Online (Sandbox Code Playgroud)

在我的基础UserControl我做

public class BaseUserControl : UserControl {
   protected void HandleClick(object sender) {
       var vm = (BaseViewModel<Part>)DataContext;
       ...
   }
}
Run Code Online (Sandbox Code Playgroud)

这会引发InvalidCastException,因为DataContext它是类型BaseViewModel但派生类型如BaseViewModel<Wire>BaseViewModel<Connector>.

我怎么能这样做?

c# oop wpf casting covariance

11
推荐指数
1
解决办法
1798
查看次数

当值类型可以相互转换时,为什么我不能将一个值类型的字典转换为另一个值类型的字典?

可能重复:
在C#中,为什么List <string>对象不能存储在List <object>变量中

以下为什么不工作?

List<string> castMe = new List<string>();
IEnumerable<string> getFromCast  = (IEnumerable<string>)castMe; // allowed.

Dictionary<int, List<string>> castMeDict = new Dictionary<int, List<string>>();
Dictionary<int, IEnumerable<string>> getFromDict = (Dictionary<int, IEnumerable<string>>)castMeDict;  // Not allowed
Run Code Online (Sandbox Code Playgroud)

这是Dictionary铸造机制中的一个缺陷,还是我认为应该允许这样做?

谢谢.

c# generics dictionary casting covariance

9
推荐指数
1
解决办法
3994
查看次数

如果要求List <IFoo>,为什么我不能返回List <Foo>?

我的理解是,如果S是一个子类的T,那么List<S>不是一个孩子List<T>.精细.但是接口有不同的范例:如果是Foo实现IFoo,那么为什么List<Foo>不是(一个例子)List<IFoo>

因为可能没有实际的类IFoo,这是否意味着我在暴露a时总是必须强制转换列表中的每个元素List<IFoo>?或者这只是糟糕的设计,我必须定义自己的集合类ListOfIFoos才能与它们一起工作?对我来说似乎都不合理......

考虑到我正在尝试编程接口,那么暴露这样一个列表的最佳方式是什么?我目前正倾向于实际存储我的List<Foo>内部作为List<IFoo>.

c# generics interface

7
推荐指数
4
解决办法
1439
查看次数

从IEnumerable <Object>转换为IEnumerable <string>

最近我在c#中发现了一个非常令人惊讶的行为.我有一个方法,它IEnumerable<Object>作为参数,我正在通过, IEnumerable<string>但它是不可能的.虽然在c#中,所有内容都可以向上转换为对象而不是为什么这是不可能的?这让我很困惑.请有人在这个问题上告诉我.

c# covariance contravariance

6
推荐指数
2
解决办法
1万
查看次数

Java/C#类型系统有哪些不足之处?

它经常听说Haskell(我不知道)有一个非常有趣的类型系统.我对Java非常熟悉,而且对C#有点熟悉,有时我会对类型系统进行战斗,所以有些设计适应或以某种方式更好地工作.

这让我想知道......

由于Java/C#类型系统的不足,以某种方式出现了什么问题?你是如何处理它们的?

c# java haskell type-systems

6
推荐指数
3
解决办法
2101
查看次数

如何将对象列表转换为对象在VB.net中实现的接口列表?

我在VB.net工作并有一个Class,Foo,它实现了一个接口,IBar.我有一个Foo列表,但我需要将一个IBar列表传递给一个函数,但即使我使用DirectCast,我仍然会出现转换错误.我的代码是

Class Foo
    Implements IBar
End Class

Interface IBar
End Interface

Sub DoIt(ByVal l As List(Of IBar))
End Sub

Sub Main()
    Dim FooList As New List(Of Foo)
    DoIt(FooList)
End Sub

Sub Main2()
    Dim FooList As New List(Of Foo)
    DoIt(DirectCast(FooList, List(Of IBar)))
End Sub

Sub MainWorks()
    Dim FooList As New List(Of Foo)
    Dim IBarList As New List(Of IBar)

    For Each f As Foo In FooList
        IBarList.Add(f)
    Next

    DoIt(DirectCast(IBarList, List(Of IBar)))
    DoIt(IBarList)
End Sub
Run Code Online (Sandbox Code Playgroud)

在主要和主要2我得到

Value of type 'System.Collections.Generic.List(Of FreezePod.Pod.Foo)' cannot be …
Run Code Online (Sandbox Code Playgroud)

.net vb.net

6
推荐指数
2
解决办法
6542
查看次数

C#编译器的泛型,继承和失败的方法解析

我今天碰到了编辑问题,这让我感到困惑.考虑这两个容器类.

public class BaseContainer<T> : IEnumerable<T>
{
    public void DoStuff(T item) { throw new NotImplementedException(); }

    public IEnumerator<T> GetEnumerator() { }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { }
}
public class Container<T> : BaseContainer<T>
{
    public void DoStuff(IEnumerable<T> collection) { }

    public void DoStuff <Tother>(IEnumerable<Tother> collection)
        where Tother: T
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

前者定义DoStuff(T item),后者DoStuff <Tother>(IEnumerable<Tother>)专门用它来解决C#的协方差/逆变的缺失(直到4听到).

这段代码

Container<string> c = new Container<string>();
c.DoStuff("Hello World");
Run Code Online (Sandbox Code Playgroud)

遇到一个相当奇怪的编译错误.请注意<char>方法调用中没有.

类型'char'不能用作泛型类型或方法'Container.DoStuff(System.Collections.Generic.IEnumerable)'中的类型参数'Tother'.从'char'到'string'没有拳击转换.

从本质上讲,编译器试图我的电话果酱DoStuff(string)进入Container.DoStuff<char>(IEnumerable<char>),因为string工具IEnumerable<char>,而不是使用BaseContainer.DoStuff(string) …

c# generics compilation

6
推荐指数
1
解决办法
923
查看次数