我是C#的新手,想使用Dictionary <>
我的代码是这样的:
public Task<IHttpActionResult> GetProgress(int id)
{
if(obj1)
{
Dictionary<string, object1> progresses = new Dictionary<string, object1>
();
}
else if(obj2)
{
Dictionary<string, object2> progresses = new Dictionary<string, object2>
();
}
return progresses;
}
在这种情况下,出现错误是因为我没有在其他情况下定义变量。
我试图这样做:
Object progresses = null;
if(obj1)
{
progresses = new Dictionary<string, object1>();
}
else if(obj2)
{
progresses = new Dictionary<string, object2>();
}
return progresses;
但是,它没有用。我遇到了“ progresses.ContainsKey()”和“ progresses.Add()”错误。
如何解决此问题? 我先谢谢了。
答案 0 :(得分:0)
C#中没有像Java这样的菱形运算符可以访问封闭类型基础的开放泛型类型,从而防止了泛型多态性。
您只能使用由Dictionary类实现的非通用接口。
答案 1 :(得分:0)
如果要使用可以采用两种不同类型的通用字典,则它们必须基于相同的基类;否则,您必须使用非通用的。
除此之外,示例中的代码没有多大意义。首先,由于要返回IHttpActionResult的Task,因此无法在此处返回字典。您要么必须返回一个新的Task(例如,通过Task.Factory.StartNew()
),要么等待返回IHttpActionResult并使用async / await语法的东西。
答案 2 :(得分:0)
突然冒出来的是您正在尝试将字典作为任务返回。那是您可能遇到的主要错误,以及为什么不能使用ContainsKey()或Add()的原因,因为这些不是Task对象的属性。我们也不知道object1 / obj1和object2 / obj2是什么。我同意其他人的看法,您应该明确说明您的目标是什么。
但是,由于不知道此方法是什么,它的用途是什么,并且不知道ASSUMING(总是一个糟糕的主意),obj1和obj2实际上是存在于全局范围内的东西,我会这样修改它:
public Dictionary<string, object> GetProgress(int id)
{
Dictionary<string, object> returnValue;
if(obj1)
{
Dictionary<string, object1> progresses = new Dictionary<string, object1>();
}
else if(obj2)
{
Dictionary<string, object2> progresses = new Dictionary<string, object2>();
}
return progresses;
}
尽管这可能会失败,而且您无法将String,Dictionary的对象隐式转换为String,“ Object1”的字典,无论是什么...
答案 3 :(得分:0)
此代码存在许多问题。让我们逐一介绍一下。
public Task<IHttpActionResult> GetProgress(int id)
{
if(obj1)
{
Dictionary<string, object1> progresses = new Dictionary<string, object1>
();
}
else if(obj2)
{
Dictionary<string, object2> progresses = new Dictionary<string, object2>
();
}
return progresses;
}
方法的返回类型为Task<IHttpActionResult>
,但您尝试返回的是Dictionary
,这是类型不匹配,并且出于显而易见的原因,编译器不喜欢它。因此,要解决的第一件事是将两者匹配,并且假设我们将返回类型更改为Dictionary
。但是,现在您面临的问题是,您基于if
试图返回两种不同类型的词典中的一种,这将不起作用。因此,现在让我们假设您总是返回一个Dictionary<string, Object1>
,以便使编译器满意。现在您还可以注意到,我们已经在两个if
语句之外声明了返回对象,因此也消除了该错误。我不确定您的obj1
和obj2
是什么,所以我在使用一些随机条件。
public Dictionary<string, Object1> GetProgress(int id)
{
Dictionary<string, Object1> progresses = new Dictionary<string, Object1>();
if (id == 1)
{
progresses = new Dictionary<string, Object1>();
}
else if (id == 2)
{
progresses = new Dictionary<string, Object1>();
}
return progresses;
}
现在,编译器很高兴,但是在两种情况下您都返回相同类型的字典。我们该如何解决?如果您简化情况,则根据您的条件,您想返回一个string
以及一个Object1
或Object2
的实例。处理此问题的一种方法是为Object1
和Object2
声明一个父类并创建该父类的字典。
public class ParentObject
{
}
public class Object1 : ParentObject
{
}
public class Object2 : ParentObject
{
}
然后,像这样创建字典:
Dictionary<string, ParentObject> progresses = new Dictionary<string, ParentObject>();
现在,根据条件,您可以将Object1
或Object2
的实例添加到字典中。
public Dictionary<string, ParentObject> GetProgress(int id)
{
Dictionary<string, ParentObject> progresses = new Dictionary<string, ParentObject>();
if (id == 1)
{
var o1 = new Object1();
progresses.Add(id.ToString(), o1);
}
else if (id == 2)
{
var o2 = new Object2();
progresses.Add(id.ToString(), o2);
}
return progresses;
}
当您调用该方法并想知道接收到的对象的类型时,可以像这样获得其Type
:
var result1 = GetProgress(1);
// Here, type = Object1
var typeOfObject1 = result1.First().Value.GetType();
var result2 = GetProgress(2);
// Here, type = Object2
var typeOfObject2 = result2.First().Value.GetType();
答案 4 :(得分:0)
要扩展先前的好答案,可以使用
缩短对象创建 (ParentObject)Activator.CreateInstance(Type.GetType($"Object{id}"))
,您还可以将Object1和Object2基于接口,以使它们实现相同的方法,例如:
public interface ParentObject
{
int Id { get; set; }
void ObjectAction(int value);
}
public class Object1 : ParentObject
{
public int Id { get; set; }
public void ObjectAction(int value)
{
Console.WriteLine("I'm object #1 with value" + value);
}
}
public class Object2 : ParentObject
{
public int Id { get; set; }
public void ObjectAction(int value)
{
Console.WriteLine("I'm different object #2 with value" + value);
}
}
public class UsingDifferentObjects
{
public Dictionary<string, ParentObject> GetProgress(int id)
{
Dictionary<string, ParentObject> progresses = new Dictionary<string,ParentObject>();
var objtoAdd = (ParentObject)Activator.CreateInstance(Type.GetType($"Object{id}"));
objtoAdd.Id = id;
progresses.Add(id.ToString(), objtoAdd);
return progresses;
}
}
所以,以后在需要时使用它们:
((ParentObject)progresses[objectKey]).ObjectAction(value);