C# 反射从接口获取具体类的静态属性

发布于 2024-11-08 23:01:12 字数 2961 浏览 0 评论 0原文

我有一个接口:

interface IInterface 
{
    string Name { get; }
}

它是由通用抽象类实现的:

public class BInterface<T> : IInterface
{
    static BInterface() 
    { 
        // Or anything that would be implementation class specific
        Name = typeof(BInterface<>).GetType().Name;  
    }
    public static string Name { get; private set; }
    string IInterface.Name { get { return Name; } }
}

它又在具体类中实现:

public class CInterface : BInterface<int> 
{
}

我知道如何通过“type.IsAssignableFrom”、“!type.IsInterface”和“获取对具体类的引用” !type.IsAbstract',但据我所知。

我需要通过反射获取任何具体类的静态 Name 属性的值。然而,就我可怜的大脑而言,我无法找出完成此任务的代码。任何提示都会很棒。

编辑(澄清):

我知道静态属性需要从基类读取。然而......

静态字段将包含具体类的基名称 -->通过基类的静态构造函数中的反射派生。这很有效(而且我知道如何实现),因为我们到处都这样做。

在这种情况下,我试图构建一个需要知道这个静态字段的工厂类,并且由于工厂实现的一些(其他)要求,需要通过反射来访问它。

编辑(再次)扩展代码:

这是我试图完成的任务的一个几乎完整(如果无用)的示例。

    public interface IInterface
    {
        string Name { get; }
        object Value { get; set; }
    }

    public class BInterface<T> : IInterface
    {
        static BInterface()
        {
            // Or anything that would be implementation class specific
            Name = typeof(BInterface<>).GetType().Name; // Should be CInterface, DInterface depending on which class it is called from.
        }

    string IInterface.Name { get { return Name; } }
    object IInterface.Value { get { return Value; } set { Value = (T)value; } }

    public static string Name { get; private set; }
    public T Value { get; set; }
}

public class CInterface : BInterface<int>
{
}

public class DInterface : BInterface<double>
{
}

public static class InterfaceFactory
{
    private readonly static IDictionary<string, Type> InterfaceClasses;

    static InterfaceFactory()
    {
        InterfaceClasses = new Dictionary<string, Type>();

        var assembly = Assembly.GetExecutingAssembly();
        var interfaceTypes = assembly.GetTypes()
                                     .Where( type => type.IsAssignableFrom(typeof (IInterface)) 
                                         && !type.IsInterface 
                                         && !type.IsAbstract);
        foreach (var type in interfaceTypes)
        {
            // Get name somehow
            var name = "...";
            InterfaceClasses.Add(name, type);
        }
    }

    public static IInterface Create(string key, object value, params object[] parameters)
    {
        if (InterfaceClasses.ContainsKey(key))
        {
            var instance = (IInterface) Activator.CreateInstance(InterfaceClasses[key], parameters);
            instance.Value = value;

            return instance;
        }
        return null;
    }
}

foreach 循环内 IntefaceFactory 的静态构造函数中的部分是我试图解决的问题。希望这更清楚。

I have an interface:

interface IInterface 
{
    string Name { get; }
}

that is implemented by an generic abstract class:

public class BInterface<T> : IInterface
{
    static BInterface() 
    { 
        // Or anything that would be implementation class specific
        Name = typeof(BInterface<>).GetType().Name;  
    }
    public static string Name { get; private set; }
    string IInterface.Name { get { return Name; } }
}

Which is in turn implemented in a concrete class:

public class CInterface : BInterface<int> 
{
}

I know how to get the references to the concrete classes via 'type.IsAssignableFrom', '!type.IsInterface' and '!type.IsAbstract', but that is as far as I have managed.

I need to get, via Reflection, the VALUE of the static Name property for any of the concrete classes. However, for the life of my poor brain, I cannot figure the code to accomplish this. Any hints would be great.

EDIT (In clarification):

I am aware that the static property needs to read from the base class. However....

The static field will contain the base name of the concrete class --> derived via reflection in the static constructor of the base class. This works (and I know how to accomplish it) as we do it all over the place.

I this case, I am attempting to build a factory class that needs to know this static field, and needs to get to it via Reflection due to the some (other) requirements of the factory implementation.

EDIT (again) Expanded code:

Here is a nearly complete, if useless, example of what I am attempting to accomplish.

    public interface IInterface
    {
        string Name { get; }
        object Value { get; set; }
    }

    public class BInterface<T> : IInterface
    {
        static BInterface()
        {
            // Or anything that would be implementation class specific
            Name = typeof(BInterface<>).GetType().Name; // Should be CInterface, DInterface depending on which class it is called from.
        }

    string IInterface.Name { get { return Name; } }
    object IInterface.Value { get { return Value; } set { Value = (T)value; } }

    public static string Name { get; private set; }
    public T Value { get; set; }
}

public class CInterface : BInterface<int>
{
}

public class DInterface : BInterface<double>
{
}

public static class InterfaceFactory
{
    private readonly static IDictionary<string, Type> InterfaceClasses;

    static InterfaceFactory()
    {
        InterfaceClasses = new Dictionary<string, Type>();

        var assembly = Assembly.GetExecutingAssembly();
        var interfaceTypes = assembly.GetTypes()
                                     .Where( type => type.IsAssignableFrom(typeof (IInterface)) 
                                         && !type.IsInterface 
                                         && !type.IsAbstract);
        foreach (var type in interfaceTypes)
        {
            // Get name somehow
            var name = "...";
            InterfaceClasses.Add(name, type);
        }
    }

    public static IInterface Create(string key, object value, params object[] parameters)
    {
        if (InterfaceClasses.ContainsKey(key))
        {
            var instance = (IInterface) Activator.CreateInstance(InterfaceClasses[key], parameters);
            instance.Value = value;

            return instance;
        }
        return null;
    }
}

The part in the static constructor of the IntefaceFactory inside the foreach loop is what I am attempting to solve. Hopefully, this is clearer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

桃酥萝莉 2024-11-15 23:01:12

这是从实例获取具体类的静态属性的方法:

var staticProperty = instance.GetType()
    .GetProperty("<PropertyName>", BindingFlags.Public | BindingFlags.Static);
var value = staticProperty.GetValue(instance, null);

This is how to get static property of concrete class from the instance:

var staticProperty = instance.GetType()
    .GetProperty("<PropertyName>", BindingFlags.Public | BindingFlags.Static);
var value = staticProperty.GetValue(instance, null);
写下不归期 2024-11-15 23:01:12

static 成员不会按照您的想法工作。它们属于基类,因此您所尝试的操作对于 static 继承成员来说是不可能的。

static members don't work the way you are thinking. They belong to the base class and thus what you are attempting is not possible with a static inherited member.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文