C#如何访问实现接口中不存在的对象属性 请考虑下面的代码。我有一个名为IClass的接口 public interface IClass { public string MyProperty { get; set; } }
我有两个类实现这个接口:C#如何访问实现接口中不存在的对象属性 请考虑下面的代码。我有一个名为IClass的接口 public interface IClass { public string MyProperty { get; set; } },c#,.net,asp.net-core,interface,polymorphism,C#,.net,Asp.net Core,Interface,Polymorphism,我有两个类实现这个接口: public class ClassA : IClass { public string MyProperty { get; set; } } public class ClassB : IClass { public string MyProperty { get; set; } public string MyProperty2 { get; set; } } public static IClass MethodA() { re
public class ClassA : IClass
{
public string MyProperty { get; set; }
}
public class ClassB : IClass
{
public string MyProperty { get; set; }
public string MyProperty2 { get; set; }
}
public static IClass MethodA()
{
return new ClassB { MyProperty = "A", MyProperty2 = "B" };
}
最后,我有一个返回IClass接口的方法:
public class ClassA : IClass
{
public string MyProperty { get; set; }
}
public class ClassB : IClass
{
public string MyProperty { get; set; }
public string MyProperty2 { get; set; }
}
public static IClass MethodA()
{
return new ClassB { MyProperty = "A", MyProperty2 = "B" };
}
我的问题是我无法从MethodA访问MyProperty2
static void Main(string[] args)
{
Console.WriteLine(JsonSerializer.Serialize(MethodA()));
}
它只返回{“MyProperty”:“A”}
如果不使用多态模型绑定,如何实际获取MyProperty2?还有其他方法吗?你需要施放
Console.WriteLine(JsonSerializer.Serialize((ClassB) MethodA()))
但是,这样做有点违背了首先使用接口的目的。可能您必须像下面那样显式地检查并强制转换它
var data = MethodA();
JsonSerializer.Serialize(data is ClassB ? data as ClassB : data as ClassA )
序列化基于您提供的类型信息。在泛型重载的情况下,这是泛型类型(序列化中的
T
)。您正在调用一个泛型重载,类型推断正在拾取IClass
。要解决此问题,请使用接受类型的:
var obj = MethodA();
var json = JsonSerializer.Serialize(obj, obj.GetType(), default);
或显式强制转换为对象
,以便将泛型类型推断为对象
:
var json = JsonSerializer.Serialize((object)MethodA(), default);
或者,二者的半组合:
var json = JsonSerializer.Serialize(MethodA(), typeof(object), default);
如果不希望序列化程序出现这种行为,则必须强制转换为显式类型(假设您知道它,并且/或者可以接受一系列类型检查)
请注意,对象
解决方案将仅在顶级/根对象上工作。如果在对象图中的某个地方有一个声明为IClass
的属性,它将不会按您所希望的方式序列化。不幸的是,您必须使用对象
类型声明这些属性
另一种方法是为您的接口类型编写一个脚本,并自己对属性进行反思。虽然对根对象(给定上述解决方案)进行了过度杀戮,但它允许您处理接口类型的嵌套对象。一个简单的转换器可以委托给对象的真实类型
public class IClassConverter : JsonConverter<IClass>
{
public override IClass Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options) => throw new NotImplementedException();
public override void Write(
Utf8JsonWriter writer,
IClass obj,
JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, obj, obj.GetType(), default); // don't pass options, will result in endless loop
}
}
MethodA()作为ClassB
?您的确切意思是什么?您需要将方法返回的对象大小写为ClassB
。可以使用(ClassB)MethodA()
或MethodA()作为ClassB
。请参阅我的答案,了解其他选项谢谢您的答案,先生,但实际上这是一个简单的示例。在真实场景中,由于通用方法,我没有机会强制转换。是否有其他方法可以实现这一点。是的,您需要在运行时使用反射来确定底层类,然后循环各种方法,并通过反射调用它们。请参阅“谢谢”,我将检查:)三元运算符没有最佳类型。这将无法使用CS0173编译