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编译