c# - tutorial - Los argumentos de tipo no se pueden inferir del uso. Intenta especificar los argumentos de tipo explícitamente
linq lambda c# (7)
¿Podría alguien aclararme algo por mí? En mi aplicación ASP.NET MVC 2, tengo una clase BaseViewModel
que incluye el siguiente método:
public virtual IDictionary<string, object> GetHtmlAttributes<TModel, TProperty>
(Expression<Func<TModel, TProperty>> propertyExpression)
{
return new Dictionary<string, object>();
}
La idea es que cada modelo de vista secundario puede anular este método y proporcionar un conjunto adecuado de atributos html, basados en cierta lógica, para ser representados en la vista:
<%: Html.TextBoxFor(model => model.MyProperty, Model.GetHtmlAttributes
(model => model.MyProperty)) %>
Sin embargo, cuando se utiliza como en la línea anterior, aparece un error de compilación cuando llego a la vista:
Los argumentos de tipo para el método ''
...BaseViewModel.GetHtmlAttributes<TModel,TProperty> Expression<System.Func<TModel,TProperty>)
'' no se pueden inferir del uso. Trate de especificar los argumentos de tipo explícitamente.
Tengo que hacer lo siguiente:
<%: Html.TextBoxFor(model => model.MyProperty, Model.GetHtmlAttributes
<ChildModel, string>(model => model.MyProperty)) %>
¿Estoy buscando algo de claridad en cuanto a cómo intenta inferir el tipo, no tiene problemas para hacerlo en el método de extensión HtmlHelper/TextBoxFor
?
¿Es porque HtmlHelper
en la vista será automáticamente para el mismo tipo que se especifica en ViewUserControl
en la parte superior de la página, mientras que mi código puede ser para cualquier tipo heredado de BaseViewModel
? ¿Es posible escribir esto de tal manera que pueda inferir mis tipos de modelo / propiedad?
C # compilador tiene solo lambda
arg => arg.MyProperty
para inferir el tipo de arg (TModel) un tipo de arg.MyProperty (TProperty). Es imposible.
En caso de que ayude, me he topado con este problema cuando pasé null
a un parámetro para un TValue
genérico, para evitar esto, tiene que emitir sus valores nulos:
(string)null
(int)null
etc.
En su ejemplo, el compilador no tiene forma de saber qué tipo debería ser TModel
. Podría hacer algo parecido a lo que probablemente está tratando de hacer con un método de extensión.
static class ModelExtensions
{
public static IDictionary<string, object> GetHtmlAttributes<TModel, TProperty>
(this TModel model, Expression<Func<TModel, TProperty>> propertyExpression)
{
return new Dictionary<string, object>();
}
}
Pero creo que no podrías tener nada similar a lo virtual
.
EDITAR:
En realidad, se puede hacer virtual
, usando genéricos autorreferenciales:
class ModelBase<TModel>
{
public virtual IDictionary<string, object> GetHtmlAttributes<TProperty>
(Expression<Func<TModel, TProperty>> propertyExpression)
{
return new Dictionary<string, object>();
}
}
class FooModel : ModelBase<FooModel>
{
public override IDictionary<string, object> GetHtmlAttributes<TProperty>
(Expression<Func<FooModel, TProperty>> propertyExpression)
{
return new Dictionary<string, object> { { "foo", "bar" } };
}
}
Este error también está relacionado con un problema de caché .
Tuve el mismo problema y se resolvió simplemente limpiando y construyendo la solución nuevamente.
Sé que esta pregunta ya tiene una respuesta aceptada, pero para mí, un principiante de .NET, había una solución simple a lo que estaba haciendo mal y pensé que lo compartiría.
Yo había estado haciendo esto:
@Html.HiddenFor(Model.Foo.Bar.ID)
Lo que funcionó para mí fue cambiar esto:
@Html.HiddenFor(m => m.Foo.Bar.ID)
(donde "m" es una cadena arbitraria para representar el objeto del modelo)
Te estás refiriendo al tipo en lugar de a la instancia. Haga ''Modelo'' en minúsculas en el ejemplo de su segundo y cuarto ejemplos de código.
Model.GetHtmlAttributes
debiera ser
model.GetHtmlAttributes
Tuve este mismo problema, mi solución:
En el archivo web.config:
<compilation debug="true>
tuvo que ser cambiado a
<compilation debug="true" targetFramework="4.0">