T不包含RowKey的定义

时间:2012-07-23 14:46:55

标签: c# .net generics compiler-errors

我正在尝试创建一个泛型类:

public class ClassName<T>
{
    public T AccessEntity(string id)
    {
        return (from e in ServiceContext.CreateQuery<T>(TableName)
                where e.RowKey == id // error here!
                select e).FirstOrDefault();
    }
}

在此代码中,我收到错误:

  

T不包含RowKey的定义

但是在运行时替换T的参数具有RowKey的定义。也许是因为编译器在编译时没有在T中获得RowKey的定义,这就是我收到此错误的原因。有谁能告诉我如何解决这个问题?

5 个答案:

答案 0 :(得分:11)

要做到这一点,你需要一个接口约束:

interface IHazRowKey {
     string RowKey { get; } 
}

并指定此限制:

public class classname<T> where T : IHazRowKey {...}

并在每个实现上指定: IHazRowKey

public class Foo : IHazRowKey {....}

现有的RowKey成员应该匹配它(假设它是属性,而不是字段),因此您不需要添加任何其他额外代码。如果它实际上是一个字段(它不应该是IMO)那么:

public class Foo : IHazRowKey {
    string HazRowKey.RowKey { get { return this.RowKey; } }
    ...
}

答案 1 :(得分:8)

C ++模板和C#泛型之间存在一个主要区别:如果编译器在编译通用时编译器不知道T上的方法,则传递实例化泛型的类并不重要类或方法,它会给你一个错误。这是因为C#需要能够从实例化的位置单独编译通用代码(请记住,C#中没有头文件)。

您可以定义一个接口,并限制T,以便在泛型中使用属性和方法。将RowKey添加到您的界面,并将where T : myinterface添加到您的通用声明。

答案 2 :(得分:3)

您需要定义constraint来解决此问题:

public interface IHasRowKey
{
   string RowKey {get;}
}

public class classname<T> where T : IHasRowKey
{

}

答案 3 :(得分:1)

class YourClass // or extract an interface
{
    public string RowKey { get; set; }
}

class YourGeneric<T> where T : YourClass
{
    // now T is strongly-typed class containing the property requested
}

答案 4 :(得分:0)

我的情况不能使用接口来包含RowKey,因为我有两个具有不同属性和方法的类。我不能只是合并它们并将这些属性和方法放在一个包装器接口或类中,因为它失去了使用泛型类的目的。我的解决方案是使用Generic类的反射。 E.g:

public class ClassName<T> {
    private T _genericType;
    public ClassName(T t) {
        _genericType = t;
    }

    public void UseGenericType() {
        // Code below allows you to get RowKey property from your generic 
        // class type param T, cause you can't directly call _genericType.RowKey
        PropertyInfo rowKeyProp = _genericType.GetType().GetProperty("RowKey");
        if(rowKeyProp != null) { // if T has RowKey property, my case different T has different properties and methods
            string rowKey = rowKeyProp.GetValue(_genericType).ToString();
            // Set RowKey property to new value
            rowKeyProp.setValue(_genericType, "new row key");
        }
    }
}

以下是对PropertyInfo类http://msdn.microsoft.com/en-us/library/System.Reflection.PropertyInfo_methods(v=vs.110).aspx

的引用