相关疑难解决方法(0)

C#通用属性限制的解决方法

随着讨论这里,C#不支持通用属性的声明.所以,我不允许做类似的事情:

[Audit<User> (UserAction.Update)]
public ActionResult SomeMethod(int id){ ...
Run Code Online (Sandbox Code Playgroud)

这就像我的属性impl类中的魅力一样,因为我需要从通用存储库中调用一个方法:

User fuuObj = (User) repository.LoadById<T>(_id);
Run Code Online (Sandbox Code Playgroud)

我尝试使用解决方案但没有成功.我可以通过类似的东西typeOf(User),但我怎么能用LoadById类型或魔术字符串调用?

*T和User都扩展了一个名为Entity的基类.

c# generics reflection

15
推荐指数
1
解决办法
2万
查看次数

C#4中是否会有通用属性?

所以 - 如果没有特殊原因没有通用属性,
我想知道 - 也许它们会被实现?

那些对ASP.NET MVC动作过滤器来说非常棒.

c# generics attributes

14
推荐指数
2
解决办法
3170
查看次数

为什么C#不允许泛型类型作为泛型类中的属性使用?

这不是一个非常重要的问题,我只是好奇为什么不允许这样做.该错误消息不是在解释有帮助的,因为很明显,"ATT" 从属性继承.

public class Generic<Att> where Att : System.Attribute
{
    [Att] //Error: 'Att' is not an attribute class
    public float number;
}
Run Code Online (Sandbox Code Playgroud)

c# generics attributes

11
推荐指数
1
解决办法
140
查看次数

强类型通用属性替代方案

让我们从一个简单的视图模型开始:

public class MyViewModel
{
  public string Value { get; set; }
  public IEnumerable<SelectListItem> Values { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

下拉列表可能如下所示:

@Html.DropDownListFor(m => m.Value, Model.Values)
Run Code Online (Sandbox Code Playgroud)

但是,因为下拉列表需要两个值,所以不能使用它:

public class MyViewModel
{
  [UIHint("DropDownList")]
  public string Value { get; set; }
  public IEnumerable<SelectListItem> Values { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

视图包含:

@Html.EditForModel()
Run Code Online (Sandbox Code Playgroud)

因为下拉知道源代码没有固有的方法,直到你从UIHint中驱逐:

public DropDownListAttribute : UIHintAttribute
{
  public DropDownListAttribute (string valuesSource)
    : base("DropDownList", "MVC")
  {
  }
}
Run Code Online (Sandbox Code Playgroud)

那么人们可能会喜欢它:

public class MyViewModel
{
  [DropDownList("Planets")]
  public string PlanetId{ get; set; }
  public IEnumerable<SelectListItem> Planets { …
Run Code Online (Sandbox Code Playgroud)

c# generics asp.net-mvc attributes automapper

9
推荐指数
1
解决办法
1249
查看次数

在属性中使用类型参数以使用带有泛型类型参数的ProducesResponseType的解决方法?

我有一个通用的ASP.NET Core WebApi控制器,如:

public abstract class EntityController<TEntity> 
{
    public IActionResult Get(string id)
    {
        var entity = ... //load from database by id
        if (entity != null) 
            return new JsonResult(value, this.SerializerSettings()) {StatusCode  200};
        return NotFound();
    }
}
Run Code Online (Sandbox Code Playgroud)

我想在Get()方法上应用以下属性:

[ProducesResponseType(typeof(TEntity), 200)] //this causes compilation error.
[ProducesResponseType(typeof(Object), 404)]
Run Code Online (Sandbox Code Playgroud)

目前,唯一的解决方法是覆盖派生控制器中的每个方法并在其中添加属性:

public class DerivedController ?EntityController<MyEntity>
{
    [ProducesResponseType(typeof(TEntity), (int) HttpStatusCode.OK)]
    [ProducesResponseType(typeof(Object), (int) HttpStatusCode.NotFound)]
    public IActionResult Get(string id)
    {
        return base.Get(id);
    }
}
Run Code Online (Sandbox Code Playgroud)

我非常不方便我应该覆盖每个控制器中的每个REST方法,只是为了使用TEntity属性中的具体类型.:-(

有没有更好的工作?

c# asp.net

8
推荐指数
2
解决办法
2137
查看次数

为什么C#属性如此有限?

我知道它们是编译时,因此它们不能是通用的,必须用常量值初始化.但是:
如果你反映出他们申请的内容,他们为什么不能获得你会得到的信息呢?
为什么他们不能接受lambda表达式,函数或委托?编译器的函数不是常量吗?

如果上面只有一个是真的,属性可能是一个非常强大的声明工具,相反,它们更像是可以通过反射阅读的注释.

这有点像咆哮,但我真的想知道为什么它们看起来像这样的半特征.

这就是我想要做的.它应该是一个API,用于将资源中的值通过给定属性的函数映射到属性应用的属性.请注意,如果Attributes可以知道它们反映的内容,则抽象类不必存在.我发布这个是因为有人想知道我为什么要为属性构造函数赋予函数,也许是因为我想要做的事情已经完成了.

public delegate void PropertyHandler(object parent, PropertyInfo property, object value);

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FromResourceAttribute : Attribute
{
    private static readonly PropertyHandler m_defaultHandler =  (parent, property, value) => 
                                                                {
                                                                    property.SetValue(parent, value, null);
                                                                };

    public PropertyHandler Handler { get; set; }

    public FromResourceAttribute(PropertyHandler handler)
    {
        Handler = handler;
    }

    public FromResourceAttribute()
    {
        Handler = m_defaultHandler;
    }
}

public abstract class ResourceDependent
{
    public ResourceDependent(ResourceManager resources)
    {
        var resourceDependentProperties = 
            from property …
Run Code Online (Sandbox Code Playgroud)

c# attributes

7
推荐指数
2
解决办法
1562
查看次数

如果仅在反映属性时构造属性,为什么属性构造函数如此有限?

如此处所示,您反映获取属性值之前,不会调用属性构造函数.但是,您可能也知道,只能将编译时常量值传递给属性构造函数.为什么是这样?我想很多人喜欢做这样的事情:

[MyAttribute(new MyClass(foo, bar, baz, jQuery)]
Run Code Online (Sandbox Code Playgroud)

而不是传递一个字符串(导致字符串类型的代码!)与这些值,变成字符串,然后依靠Regex尝试获取值而不是仅使用实际值,而不是使用编译时警告/错误取决于对于可能抛出与该类无关的异常,除了它调用的方法使用了一些键入错误的属性.

这有什么限制?

c# attributes

6
推荐指数
1
解决办法
569
查看次数

已知类型属性不能使用类型参数

我有这个 Web Api 控制器操作:

public Plant<TissueProductionLine> GetPlant(string plant, string range)
{
    return _repo.GetPlant(plant, range);
}
Run Code Online (Sandbox Code Playgroud)

启动这个我得到这个:

不应键入数据合同名称为“IGMProdLineDashboard.Models”的“IGMProdLineDashboard.Models.TissueProductionLineGroup”。考虑使用 DataContractResolver 或将任何静态未知的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将它们添加到传递给 DataContractSerializer 的已知类型列表中。

好的,没问题,我将Plant[KnownType]属性装饰我的对象并指定非原始属性:

[KnownType(typeof(ProductionLineGroups<T>))]
public class Plant<T>: IPlant<T> where T : IProductionLine
{
    public Plant ()
    {
        ProductionLineGroups = new ProductionLineGroups<T>();
    }
    public ProductionLineGroups<T> ProductionLineGroups { get; set; }
Run Code Online (Sandbox Code Playgroud)

现在我得到一个编译时错误:

'IGMProdLineDashboard.Models.ProductionLineGroups':属性参数不能使用类型参数

重读第一条消息,它想知道派生类型: TissueProductionLineGroup

如果我Plant用这个装饰我的对象,一切正常:

[KnownType(typeof(TissueProductionLineGroup))]
Run Code Online (Sandbox Code Playgroud)

显然,这里的含义是我Plant现在需要了解所有不同类型的生产线,这意味着Plant每当添加新组时我都需要更新。

有没有办法解决?

c# asp.net asp.net-web-api

6
推荐指数
1
解决办法
4111
查看次数

在属性中键入约束

我想用自定义属性编写枚举,例如:

public enum SomeEnum: long
{
    [SomeAttribute<MyClass1>]
    Sms = 1,
    [SomeAttribute<MyClass2>]
    Email = 2
}
Run Code Online (Sandbox Code Playgroud)

但属性不支持泛型.嗯,最类似的解决方案是:

public enum SomeEnum: long
{
    [SomeAttribute(typeof(MyClass1))]
    Sms = 1,
    [SomeAttribute(typeof(MyClass2))]
    Email = 2
}
Run Code Online (Sandbox Code Playgroud)

这里有问题:我想Class1继承ICustomInterface,所以使用泛型我可以编写约束:

[AttributeUsage(AttributeTargets.All)]
class SomeAttribute<T> : Attribute where T: ICustomInterface
{
}
Run Code Online (Sandbox Code Playgroud)

但属性不支持泛型.

所以最后的问题是:如何检查编译时间(如T约束)该类型是否正在实现某些接口?

.net c# generics reflection custom-attributes

6
推荐指数
1
解决办法
3063
查看次数

如何在不将其写入C#中的字符串文字的情况下引用标识符?

我经常想这样做:

public void Foo(Bar arg)
{
  throw new ArgumentException("Argument is incompatible with " + name(Foo));
}
Run Code Online (Sandbox Code Playgroud)

因为如果我更改了Foo的名称,IDE也会重构我的错误消息,如果我将方法的名称(或任何其他类型的成员标识符)放在字符串文字中,将不会发生什么.我知道实现"名称"的唯一方法是使用反射,但我认为性能损失超过了可持续性增益,并且它不会涵盖所有类型的标识符.

括号之间的表达式的值可以在编译时计算(如typeof),并通过更改语言规范进行优化以成为一个字符串文字.你认为这是一个有价值的功能吗?

PS:第一个例子看起来问题只与例外有关,但事实并非如此.想想您可能想要引用类型成员标识符的每种情况.你必须通过字符串文字来做,对吗?

另一个例子:

[RuntimeAcessibleDocumentation(Description="The class " + name(Baz) +
  " does its job. See method " + name(DoItsJob) + " for more info.")]
public class Baz
{
  [RuntimeAcessibleDocumentation(Description="This method will just pretend " +
    "doing its job if the argument " + name(DoItsJob.Arguments.justPretend) +
    " is true.")]
  public void DoItsJob(bool justPretend) 
  {
    if (justPretend)
      Logger.log(name(justPretend) + "was true. …
Run Code Online (Sandbox Code Playgroud)

c#

5
推荐指数
3
解决办法
574
查看次数