我可能目前感到困惑,但我有以下问题。 我正在使用C#,但重点更为通用,但我是来自Java的C#的新手。
我有一个共同的抽象超类和多个孩子。 有些孩子有通用属性,当我在声明公共超类型时实例化变量时,我无法访问这些属性:
abstract class A
{
public string Prop0;
}
// Here every ok when instantiated
class B: A
{
public string Prop1;
}
// This makes trouble
class C<T> : A
{
public T Prop2;
}
现在我有一个返回A:
的子类型的方法public A DoIt()
{
A a;
a = new C<string>();
a.Prop2; // <-- Can't access
}
(在我的具体情况下,类型不能是静态的,因为子类是序列化的并且具有不同的形状(C是具有允许任何内容的属性的模板)。仍然是一般的问题)
为什么这是一个问题,哪个解决方案是“正确的”(除了使用“对象”)
答案 0 :(得分:3)
如果始终将a
设置为C
的新实例,则只需将其声明为:
public A DoIt()
{
C<string> c;
c = new C<string>();
var prop2 = c.Prop2;
return c;
}
但是,如果你不知道它是否是C
,直到它被反序列化 - 这听起来就是你的解释就是这里的情况 - 那么这是一种获得该属性的方法,如果事实上它是C
(如果不是null
,则获取C
):
public A DoIt()
{
A a;
a = new C<string>();
var prop2 = a is C<string> ? (a as C<string>).Prop2 : null;
return a;
}
基本上,第二种方法的作用是检查a
是C
的实例,如果是,则将a
转换为C
,然后读取Prop2
财产。
后续示例:
这是来自实际工作控制台应用程序的代码,它与您所描述的内容类似。这不是一个现实的场景,它可能与您的想法不太接近,但无论如何我会发布它,以防它给你任何想法。
请注意,这需要引用Json.NET(对于下面的using Newtonsoft.Json;
声明)。
using System;
using Newtonsoft.Json;
...
static void Main(string[] args)
{
var c = new C<string>() { Prop0 = "zero", Prop2 = "two" };
var json = JsonConvert.SerializeObject(c);
var prop2 = GetProp2(json);
Console.WriteLine("prop2 from C: " + (prop2 ?? "null"));
var b = new B() { Prop0 = "zero", Prop1 = "one" };
json = JsonConvert.SerializeObject(b);
prop2 = GetProp2(json);
Console.WriteLine("prop2 from B: " + (prop2 ?? "null"));
Console.Write("Press any key to exit...");
Console.ReadKey();
}
static object GetProp2(string json)
{
A a = JsonConvert.DeserializeObject<C<string>>(json);
var prop2 = a is C<string> ? (a as C<string>).Prop2 : null;
return prop2;
}
结果如下:
prop2 from C: two
prop2 from B: null
Press any key to exit...
答案 1 :(得分:1)
评论中问题的可能答案:“您如何声明Shape
的某些子类型将被返回/实例化。”
如果您想要专门返回C<T>
结果,可以将其指定为返回类型:
public C<TResult> DoIt<TResult>()
{
C<TResult> a;
a = new C<TResult>();
a.Prop2; // <-- Can access
return a;
}