Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# T不包含RowKey的定义_C#_.net_Generics_Compiler Errors - Fatal编程技术网

C# T不包含RowKey的定义

C# T不包含RowKey的定义,c#,.net,generics,compiler-errors,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).FirstOrD

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

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的定义,这就是为什么我得到这个错误。有人能告诉我如何解决这个问题吗?

您需要定义以解决这个问题:

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
}
public interface IHasRowKey
{
   string RowKey {get;}
}

public class classname<T> where T : IHasRowKey
{

}

<> P> C++模板和C泛型之间有一个很大的区别:你传递的实例化泛型类并不重要,如果编译器在编译泛型类或方法时不知道T上的方法,它会给你一个错误。这是因为C需要能够独立于实例化位置编译泛型代码记住,C中没有头


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

为此,您需要一个接口约束:

interface IHazRowKey {
     string RowKey { get; } 
}
并指定此限制:

public class classname<T> where T : IHazRowKey {...}
假设现有的RowKey成员是一个属性,而不是一个字段,则应该与之匹配,因此不需要添加任何其他额外代码。如果它实际上是一个不应该是的领域,IMO则:

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

我的案例无法使用接口包含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类的引用,它不应该是ICanHazRowKey吗感谢您的回答,但是我作为泛型类实现的类是从另一个类派生的,很抱歉没有在问题中提到这一点。表示它类似于:public class ClassName:Base@Tom这不会改变任何事情;允许多接口继承和单类继承,是否可以不在类实现中添加:IHazRowKey?例如,如果定义了相应的方法,我想创建一个通用函数来切换控件的隐藏/扩展,当然,这里没有办法修改Microsoft的代码。@Hi Angel,你是在问是否可以让现有类实现接口?如果是这样的话:不。你必须包装它,装饰风格。当然,除非它只是在同一个程序集中生成的代码,在这种情况下:部分类作为注释-我对正确答案中的一个进行了投票:编译器不关心T稍后会是什么。它关心它在编译时知道什么,这意味着您可以创建类名,Dumbo没有RowKey->错误。添加约束;Pro演示了TomTom的观点:在c中,您可以在运行时编写一个类型,并为新类型调用泛型类型——只要它满足约束,它就可以工作。这与C++模板非常不同。
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");
        }
    }
}