c# - 如何从抽象类中的静态方法获取当前类型?

标签 c# static attributes types

如何获取当前的 Type在抽象类中定义的静态方法中?

请注意,由于该方法是在抽象类中定义的,所以我不能使用 typeof .

我为什么要这样做?一种可能的用法是属性。考虑以下示例:

[Identifier(1000)]
public class Rock : Entity { }

public abstract class Entity
{
    public static ushort Identifier
    {
        get
        {
            // How do I get here the current type of the object?
            Type currentType = ...;

            // in a non-static method or property, I'd do:
            // Type currentType = this.GetType();

            foreach (IdentifierAttribute attribute in currentType.GetCustomAttributes(true))
                return attribute.Identifier;

            throw new EntityException("No identifier has specified for this type of entity.");
        }
    }
}

Rock rock = new Rock();

// should print 1000
Console.WriteLine(rock.Identifier);

编辑:

这是场景。

实体表示一个 3D 对象。我正在编写一个服务器软件,其中包含此类实体的列表。服务器手动序列化列表并将其发送给客户端。由于性能在这里非常重要,因此我不会发送类型名称。每种类型的实体都有一个唯一的标识符,因此当客户端获取数据时,它可以高效地反序列化它。

要创建一个实体的实例,我正在做类似的事情:

Entity entity = EntityRepository.Instance.CreateNew(identifier);

EntityRepository类看起来像这样:

public sealed class EntityRepository
{
    private static readonly Lazy<EntityRepository> lazy =
        new Lazy<EntityRepository>(() => new EntityRepository());

    IDictionary<ushort, Func<Entity>> _repo;

    private EntityRepository()
    {
        _repo = new Dictionary<ushort, Func<Entity>>();
    }

    public static EntityRepository Instance 
    { 
        get { return lazy.Value; } 
    }

    public Entity CreateNew(ushort id)
    {
        return _repo[id]();
    }

    public void Add<T>(ushort id)
        where T : Entity, new()
    {
        _repo.Add(id, new Func<Entity>(() =>
        {
            return new T();
        }));
    }
}

当前Add<T>方法有一个代表标识符的参数。

但是我怎么写 Add<T>没有参数的方法 - 自动识别标识符?

所以我在考虑为嵌套的 Entity 添加一个属性:

[Identifier(1000)]
public class Rock : Entity { }

和一个返回 Identifier 值的静态属性属性。

然后,Add<T>没有参数的方法看起来像:

public void Add<T>(ushort id)
    where T : Entity, new()
{
    _repo.Add(T.Identifier, new Func<Entity>(() =>
    {
        return new T();
    }));
}

请注意,在这种情况下,我可以做 T.GetType()获取属性,但这不是重点。我怎样才能在静态属性中做到这一点,Entity.Identifier

最佳答案

基本上你不能。

Rock.Identifier 的调用将由编译器解析为 Entity.Identifier - 根本没有任何上下文可以找到类型。

调用 rock.Identifier 甚至无法编译,因为您正试图通过变量访问静态成员。

最佳解决方法取决于真实场景 - 如果您已发布,我建议在别处创建一个静态方法,该方法接受一个类型作为参数。

实际上,您可以通过使用 Rock 的编译时类型以非常可怕的方式为您的特定场景伪造它:

public static class NastyExtensions
{
    public static ushort GetIdentifier<T>(this T actualValueIsIgnored)
    {
        Type type = typeof(T);
        ... code as before
    }
}

然后:

Rock rock = new Rock();
Console.WriteLine(rock.GetIdentifier());

但这不会是多态的。例如:

Entity rock = new Rock();
Console.WriteLine(rock.GetIdentifier()); // Bang! T would be Entity here

当然,您可以更改扩展方法以调用 GetType()...

关于c# - 如何从抽象类中的静态方法获取当前类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6749275/

相关文章:

java - 为什么 Java 不允许在构造函数中初始化 static final 变量(例如 static final int d)?

attributes - @nogc 属性是否在 d 中实现?

C# 结构 "this = ...."

java - 枚举可以是非静态的吗?

java - 不能 `import static`静态嵌套类?

c# - 防止其他开发人员在类中使用基方法

python - 获取子类的属性

c# - 如何使用线程模拟 Task.Wait

c# - Metro风格的应用UI设计: Pages vs Scenarios

c# - wpf-单击按钮时动态创建新文本框和文本 block 并将其添加到网格行