简体   繁体   English

设置实现接口的类的所有成员来自接口类型的对象,而不需要在C#中编写大量代码

[英]Set all members of class that implements an interface from an object of the interface type without a lot of writing code in C#

It may sound a little bit complicated but I will try to explain it clearly. 听起来有点复杂,但我会尽力解释清楚。

Is it possible in C# if I have a long interface : 如果我有一个很长的接口,它是否可以在C#中:

public interface IInterface
{
    bool interface_1;
    bool interface_2;
    bool interface_3;
    bool interface_4;
    bool interface_5;
    ...
}

And a class that implements the interface 还有一个实现接口的类

public class MyClass : IInterface
{
    ...
}

Imagine I have an object of IInterface myInterface, is there a way to create a MyClass object myClass and to set all fields of myClass with the one of myInterface without setting all fields one by one. 想象一下,我有一个IInterface myInterface的对象,有没有办法创建一个MyClass对象myClass,并用myInterface设置myClass的所有字段,而不是逐个设置所有字段。 Like : 喜欢 :

IInterface myInterface;
MyClass myClass;
myClass.SetIInterface(myInterface);

Imagine I have an object of IInterface myInterface, is there a way to create a MyClass object myClass and to set all fields of myClass with the one of myInterface 想象一下,我有一个IInterface myInterface的对象,有没有办法创建一个MyClass对象myClass,并用myInterface设置myClass的所有字段

This is fundamentally flawed. 这基本上是有缺陷的。 You cannot have an object of an interface, only an object of a class that implements the interface. 您不能拥有接口的对象,只能拥有实现接口的类的对象。 Furthermore, an interface cannot have fields, only properties, events and methods. 此外,接口不能包含字段,只能包含属性,事件和方法。 The interface declaration in your snippet can never compile. 您的代码段中的接口声明永远无法编译。 Furthermore, the odds that the passed object has any fields in common with your class are slim to none, unless they have a base class in common that declares the fields. 此外,传递的对象具有与您的类共有的任何字段的可能性很小,除非它们具有声明字段的共同基类。

You'll need a base class instead of an interface. 你需要一个基类而不是一个接口。 Copying the field values is now trivial and quick. 现在,复制字段值非常简单快捷。

Yes, you can do that using reflection . 是的,你可以用反射做到这一点。 Use typeof(IInterface).GetProperties() (interfaces cannot define fields) to retrieve a list of properties you'd like to get or set, and use the appropriate methods on the returned object to do that (eg PropertyInfo.GetValue() and PropertyInfo.SetValue() ). 使用typeof(IInterface).GetProperties() (接口不能定义字段)来检索您想要获取或设置的属性列表,并在返回的对象上使用适当的方法来执行此操作(例如PropertyInfo.GetValue()PropertyInfo.SetValue() )。

You can easily do that using reflection. 您可以使用反射轻松完成此操作。 You reflect over all the public properties of the interface, read the value from the passed IInterface and write that value into a new object of MyClass : 您可以反映接口的所有公共属性,从传递的IInterface读取值并将该值写入MyClass的新对象:

public interface IInterface
{
    bool interface_1 { get; set; }
}

public class MyClass : IInterface
{

}

public class ReflectionHelper
{
    private MyClass CreateByCopy(IInterface instance)
    {
        MyClass obj = new MyClass();
        foreach (PropertyInfo property in typeof( IInterface ).GetProperties())
        {
            property.SetValue( property, property.GetValue( instance, null ), null );
        }

        return obj;
    }
}

Make sure you handle indexer properties correctly, should you have them. 如果有的话,请确保正确处理索引器属性。 I must warn you though, this approach will have horrible performance. 我必须警告你,这种做法会有可怕的表现。 But it should be fine if you are not creating a lot of objects this way. 但是如果你不是用这种方式创建很多对象的话应该没问题。

这与这个老问题非常相似 - 答案是一样的:如果你正在做这样的事情(并且没有说明为什么它与你不同的好理由),你就处于AutoMapper领域(或即将写一个苍白的模仿它)

Sure there is. 当然有。 You can define the SetIInterface() method in the class (and/or the interface) and handle the setting of fields one-by-one in one place. 您可以在类(和/或接口)中定义SetIInterface()方法,并在一个位置逐个处理字段设置。 You could also define an extension method if you didn't have control over the code for MyClass or IInterface. 如果您无法控制MyClass或IInterface的代码,也可以定义扩展方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM