5

我正在尝试创建一个通用类:

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 的定义,这就是我收到此错误的原因。谁能告诉我如何解决这个问题?

4

5 回答 5

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; } }
    ...
}
于 2012-07-23T14:50:23.397 回答
8

C++ 模板和 C# 泛型之间有一个主要区别:传递什么类来实例化泛型并不重要,如果编译器T在编译泛型类或方法时不知道某个方法,它会给你一个错误。这是因为 C# 需要能够将通用代码与其实例化位置分开编译(请记住,C# 中没有标头)。

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

于 2012-07-23T14:50:14.410 回答
3

您需要定义约束来解决这个问题:

public interface IHasRowKey
{
   string RowKey {get;}
}

public class classname<T> where T : IHasRowKey
{

}
于 2012-07-23T14:49:43.827 回答
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
}
于 2012-07-23T14:49:07.943 回答
0

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

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

于 2014-09-25T01:56:09.827 回答