我正在尝试将一个列表传递给一个列表的DerivedClass函数BaseClass,但是我得到了错误:
cannot convert from
'System.Collections.Generic.List<ConsoleApplication1.DerivedClass>'
to
'System.Collections.Generic.List<ConsoleApplication1.BaseClass>'
Run Code Online (Sandbox Code Playgroud)
现在我可以把我List<DerivedClass>投入到一个List<BaseClass>,但我不觉得这样做,除非我理解为什么编译器不允许这样做.
我发现的解释只是说它以某种方式违反了类型安全,但我没有看到它.谁能帮我吗?
什么是编译器允许从转换的风险List<DerivedClass>来List<BaseClass>?
这是我的SSCCE:
class Program
{
public static void Main()
{
BaseClass bc = new DerivedClass(); // works fine
List<BaseClass> bcl = new List<DerivedClass>(); // this line has an error
doSomething(new List<DerivedClass>()); // this line has an error
}
public void doSomething(List<BaseClass> bc)
{
// do something with bc
}
}
class BaseClass
{
}
class DerivedClass : BaseClass
{ …Run Code Online (Sandbox Code Playgroud) 以下代码给出了这个错误:
无法从'System.Collections.Generic.List'转换为'System.Collections.Generic.List'.
如何向编译器指出Customer确实从对象继承?或者它只是不与泛型集合对象继承(发送List<string>获取相同的错误).
using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;
namespace TestControl3423
{
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
List<Customer> customers = Customer.GetCustomers();
FillSmartGrid(customers);
//List<CorporateCustomer> corporateCustomers = CorporateCustomer.GetCorporateCustomers();
//FillSmartGrid(corporateCustomers);
}
public void FillSmartGrid(List<object> items)
{
//do reflection on items and display dynamically
}
}
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Street { get; set; }
public string Location { …Run Code Online (Sandbox Code Playgroud) 给出以下类型:
public interface IPrimary{ void doBattle(); }
// an ISecondary "is" an IPrimary
public interface ISecondary : IPrimary { }
// An implementation of ISecondary is also an IPrimary:
internal class SecondaryImpl : ISecondary
{
// Required, since this is an IPrimary
public void doBattle(){ }
}
Run Code Online (Sandbox Code Playgroud)
为什么我不这样做?
List<IPrimary> list = new List<ISecondary>();
Run Code Online (Sandbox Code Playgroud)
这会导致以下编译错误:
参数类型'System.Collections.Generic.List'的参数类型不可分配给参数类型'System.Collections.Generic.List'
我理解错误,我意识到有一些解决方法.我只是没有看到任何明确的原因,为什么不允许这种直接转换.包含在列表中的值ISecondary,应毕竟是(通过扩展)类型的值IPrimary然后被.为什么List<IPrimary>和List<ISecondary>被解释为不相关的类型?
任何人都可以清楚地解释C#以这种方式设计的原因吗?
一个稍微扩展的例子:我在尝试执行类似以下操作时遇到了这个问题:
internal class Program
{
private static void Main(string[] args)
{
// Instance of …Run Code Online (Sandbox Code Playgroud) 我试图弄清楚为什么在第一种情况下不能进行类型转换,但在第二种情况下它是可能的.请看下面的代码:
var strList = new List<string>{"One", "Two", "Three"};
List<object> objList = (List<object>) strList; // <<<< why is not converted? - Case 1
IEnumerable<object> ienumList = strList; // <<<< why is converted? - Case 2
Run Code Online (Sandbox Code Playgroud) 我有一个无法解决的铸造问题:
在 ClassA 初始化函数中,我想将“this”作为参数传递,但编译器无法从 转换ClassA<T, U>为ClassA<ClassB<U>, U>知道它们是相同的 ( where T : ClassB<U>)。
public class ClassA<T, U> : MonoBehaviour where T : ClassB<U>
{
public void initialize()
{
T item =...
item.Initialize(this); // Cannot implicitly convert from ClassA<T, U> to ClassA<ClassB<U>, U>.
}
}
public class ClassB<T> : MonoBehaviour
{
public virtual void Initialize(ClassA<ClassB<T>, T> mgr, T data)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢。
我知道我可以将一个对象从它自己的类型转换为它的接口类型,如下所示:
IMyInterface myValue = (IMyInterface)MyObjectThatImplementsMyInterface;
Run Code Online (Sandbox Code Playgroud)
我怎样才能投IList<MyClassThatImplementMyInterface>来IList<IMyInterface>?
如果我有两个班:
public class A { }
public class B : A { }
Run Code Online (Sandbox Code Playgroud)
我创建了一个通用容器和一个接受它的函数:
public void Foo(List<A> lst) { ... }
Run Code Online (Sandbox Code Playgroud)
如果我尝试将a转换List<B>为a List<A>,则会得到无效的转换,而不是像这样传递它:
var derivedList = new List<B>();
Foo(new List<A>(derivedList));
Run Code Online (Sandbox Code Playgroud)
有没有办法将a传递List<B>给这个函数而没有分配全新列表的开销,或者C#不支持从派生类型的通用容器转换到它的基类型?
我有一个泛型类型G<T> where T : A,其中A是一个抽象类.在每个B派生的类中,A我希望有一个类型的字段G<B>,而不需要编写重复代码,但是我不确定它是否可能.一种方法是这样做
abstract class A
{
protected object g;
protected abstract void SetG();
public A()
{
SetG();
}
}
class B : A
{
protected override void SetG()
{
this.g = new G<B>();
}
public B() : base() {}
}
Run Code Online (Sandbox Code Playgroud)
但这意味着每个派生类中都会有很多重复代码.有一个更好的方法吗?
让我们考虑一个抽象基类和一个或多个子类:
public abstract class BaseInnerClass
{
public int Id { get; set; }
}
public class ConcreteInnerClass : BaseInnerClass
{
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后,我们假设有一个通用抽象类,它具有以上抽象类类型的属性:
public abstract class GeneriAbstractTestClass<T> where T : BaseInnerClass
{
public T InnerClass { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后让我们创建一个继承自上面类的类:
public class ConcreteTestClass : GeneriAbstractTestClass<ConcreteInnerClass>
{
public string ConcreteString { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
所以现在一切都准备问一个问题;)为什么不可能这样做:
//cannot convert initializer type
GeneriAbstractTestClass<BaseInnerClass> genericClass = new ConcreteTestClass();
Run Code Online (Sandbox Code Playgroud)
虽然这是允许的:
//ok
BaseInnerClass baseInner = new ConcreteInnerClass();
Run Code Online (Sandbox Code Playgroud)
这两项任务有什么区别?
我正在尝试使用方法创建界面
void Import(int id, IDictionary<int, IDictionary<int, string>> items);
Run Code Online (Sandbox Code Playgroud)
然后像这样调用这个方法
Dictionary<int, Dictionary<int, string>> items = viewModel.Items
.GroupBy(t => t.Number)
.ToDictionary(t => t.Key, t => t.ToDictionary(x => x.LanguageId, x => x.Translation));
Import(id, items);
Run Code Online (Sandbox Code Playgroud)
我预计它应该有效,但出现错误
cannot convert from 'System.Collections.Generic.Dictionary<int, System.Collections.Generic.Dictionary<int, string>>' to 'System.Collections.Generic.IDictionary<int, System.Collections.Generic.IDictionary<int, string>>'
Run Code Online (Sandbox Code Playgroud)
为什么我不能在这里使用接口 IDictionary ?我应该手动投射吗?
我在Windows 7上的Visual Studio 2013 Pro中使用C#5/.NET 4.5.
我想处理项目集合,其中唯一的要求是项目实现特定的接口.集合中的项目不一定是公共继承树的一部分(即集合不会基于共同的祖先),它们可以是任意类,但都将实现指定的接口(因此目标是基于集合)在他们都实现的通用接口上).
我遇到了麻烦.如果我有一组实现所需接口的项目,我无法将该集合传递给需要基于接口的集合的方法.
这里有一些代码可以使它更具体.
using System.Collections.Generic;
class Test
{
public interface IDrawable
{
void Draw();
}
public class Shape : IDrawable
{
public void Draw() {}
}
public void DrawItems(List<IDrawable> itemsToDraw) {}
public Test()
{
List<Shape> shapes = new List<Shape>();
DrawItems(shapes);
}
}
Run Code Online (Sandbox Code Playgroud)
对DrawItems的调用会生成编译器错误.该方法期望实现IDrawable的项集合.我正在传递一组Shape对象.由于Shape对象确实实现了IDrawable,我希望我可以逃脱这个.
看起来这不起作用,但我想了解原因.我查阅了关于协方差和逆变的信息,但没有找到任何专门针对这种情况的信息.
关于为什么这不起作用的任何想法或信息?
c# ×11
generics ×6
.net ×2
interface ×2
list ×2
casting ×1
dictionary ×1
inheritance ×1
types ×1