【问题标题】:Using a class's Attribute parameter's value in as a Property's attribute value in C#在 C# 中使用类的 Attribute 参数值作为 Property 的属性值
【发布时间】:2017-11-30 23:33:05
【问题描述】:

我有一个class,它有一个属性,上面有一个属性:

public class MyClass
{
    [CustomAttribute]
    public CustomObject Data { get; set; }
}

CustomAttribute 有一个参数,我希望能够在代码中的各个点设置一个编译时常量。

我的问题是:是否可以执行如下所示的操作

public class MyClass
{
    // --- Based on the below code, Parameter should be 123
    [CustomAttribute(Parameter = HelperAttribute.Value)]
    public CustomObject Data { get; set; }
}

// ...

// --- Create a new instance of MyClass, and use the value 
// --- 123 for Data's CustomAttribute Parameter.
[HelperAttribute(Value = 123)]
public MyClass Obj { get; set; }

注意:我知道我不能在编译时进行反射部分。我很好奇是否有一种内置于 C# 中的方法。

【问题讨论】:

  • 如果您多次使用该属性,编译器如何知道要使用HelperAttribute.Value 的哪个“实例”?
  • 这是什么栈?您将使用您正在使用的堆栈中的一个功能来传递值(例如,在 Web Api 2 中它是 httpcontext)。
  • @RandomUs1r,基本 C#。
  • @KennethK。编译器真的很聪明是我最好的答案。不过,你确实提出了一个很好的观点。
  • @David Ah 在我头顶上,从未尝试过...看看stackoverflow.com/questions/6637679/…stackoverflow.com/questions/6637679/…。注意反思的共同主题,不确定过去。

标签: c# custom-attributes


【解决方案1】:

这是个好主意。但这对属性设计师来说毫无意义。属性值应该由runtine编译器元数据通过反射检索然后创建属性实例。

【讨论】:

    【解决方案2】:

    我认为不可能在运行时通过反射更改属性属性值,因为属性是在编译时使用的元数据序列化

    【讨论】:

    • 是的,我知道我不能使用反射。我希望 C# 中内置了某种方法来做到这一点。我展示的代码都是编译时常量,它只允许一个实例为 123,另一个实例为 321。
    【解决方案3】:

    这是不可能的,因为属性构造函数只允许编译时常量。你甚至不能做这样的事情:

    public class MyClass
    {
        static int test = 5;
        [CustomAttribute(Parameter = test)]
        public object Data { get; set; }
    }
    

    【讨论】:

    • 从技术上讲,我的代码中的所有内容都是编译时间常数。
    • 不,HelperAttribute.Value 必须是一个变量。否则你会如何在构造函数中设置它?
    • 那个特定的部分是假的,因为我不知道是否有正确的方法(我假设现在没有)。
    【解决方案4】:

    属性与类型(类)相关联,而不是与实例相关联。有一个值,在编译时固定。

    但是,您可以使用该属性来初始化该值。

    [MyInitializer(Value = "Test")]
    class Test
    {
        public Test()
        {
            this.Value = this.GetType().GetAttributes().OfType<MyInitializerAttribute>().Value;
        }
    
        public string Value { get; set; }
    }
    

    我不太明白这一点,因为您可以轻松地将其初始化为一个常量值,这比添加属性需要更少的输入,并且可能更清晰。

    class Test
    {
        public Test()
        {
            this.Value = "Test"; 
        }
    
        public string Value { get; set; }
    }
    

    或使用 C# 6

    class Test
    {
        public string Value { get; set; } = "Test";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-16
      • 2019-12-16
      • 1970-01-01
      • 2015-12-08
      • 2014-12-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多